Compare commits
3 Commits
epr-pineci
...
cmake
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c17b0443c | ||
|
|
22d0b0d643 | ||
|
|
e6a080c33d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -177,3 +177,5 @@ fabric.properties
|
||||
CoreCompileInputs.cache
|
||||
.vscode/settings.json
|
||||
source/compile_commands.json
|
||||
source/build/
|
||||
source/null.cpp
|
||||
|
||||
@@ -9,7 +9,7 @@ WORKDIR /build
|
||||
# musl-dev is required for the multi lang firmwares
|
||||
# clang is required for clang-format (for dev)
|
||||
|
||||
RUN apk add --no-cache gcc-riscv-none-elf gcc-arm-none-eabi newlib-riscv-none-elf newlib-arm-none-eabi findutils python3 py3-pip make git musl-dev clang bash clang-extra-tools
|
||||
RUN apk add --no-cache gcc-riscv-none-elf gcc-arm-none-eabi newlib-riscv-none-elf newlib-arm-none-eabi findutils python3 py3-pip make git musl-dev clang bash clang-extra-tools cmake
|
||||
|
||||
# Install Python3 packages
|
||||
|
||||
|
||||
9
source/CMake/arm-gcc.cmake
Normal file
9
source/CMake/arm-gcc.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
# which compilers to use for C and C++
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
set(CMAKE_C_COMPILER arm-none-eabi-gcc CACHE INTERNAL "C Compiler")
|
||||
set(CMAKE_CXX_COMPILER arm-none-eabi-g++ CACHE INTERNAL "C++ Compiler")
|
||||
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc -x assembler-with-cpp CACHE INTERNAL "ASM Compiler")
|
||||
set(CMAKE_OBJCOPY arm-none-eabi-objcopy CACHE INTERNAL "Object Copy")
|
||||
set(CMAKE_OBJDUMP arm-none-eabi-objdump CACHE INTERNAL "Object Dump")
|
||||
|
||||
|
||||
6
source/CMake/gd32vf1.cmake
Normal file
6
source/CMake/gd32vf1.cmake
Normal file
@@ -0,0 +1,6 @@
|
||||
# core flags
|
||||
|
||||
set(CORE_FLAGS "-march=rv32imac -mabi=ilp32 -mcmodel=medany -fsigned-char -fno-builtin -nostartfiles" CACHE INTERNAL "CPU flags")
|
||||
add_definitions(${CORE_FLAGS})
|
||||
# link with linker file
|
||||
target_link_libraries(${elf_file} PUBLIC -T ${CMAKE_CURRENT_SOURCE_DIR}/linkers/gd32vf103.ld)
|
||||
9
source/CMake/riscv-gcc.cmake
Normal file
9
source/CMake/riscv-gcc.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
# which compilers to use for C and C++
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
set(CMAKE_C_COMPILER riscv-none-elf-gcc CACHE INTERNAL "C Compiler")
|
||||
set(CMAKE_CXX_COMPILER riscv-none-elf-g++ CACHE INTERNAL "C++ Compiler")
|
||||
set(CMAKE_ASM_COMPILER riscv-none-elf-gcc -x assembler-with-cpp CACHE INTERNAL "ASM Compiler")
|
||||
set(CMAKE_OBJCOPY riscv-none-elf-objcopy CACHE INTERNAL "Object Copy")
|
||||
set(CMAKE_OBJDUMP riscv-none-elf-objdump CACHE INTERNAL "Object Dump")
|
||||
|
||||
|
||||
26
source/CMake/shared-compiler-settings.cmake
Normal file
26
source/CMake/shared-compiler-settings.cmake
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
# set additional for compiler and linker: optimization and generate map file
|
||||
set(additional_linker_flags -Wl,-Map=${map_file},--cref,--no-warn-mismatch)
|
||||
target_link_libraries(${elf_file} PRIVATE ${additional_linker_flags})
|
||||
|
||||
# remove unused sections
|
||||
target_link_libraries(${elf_file} PUBLIC "-Wl,--gc-sections -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--undefined=vTaskSwitchContext -Wl,--undefined=pxCurrentTCB --specs=nosys.specs -Wl,--print-memory-usage -flto")
|
||||
|
||||
set(TARGET_FLAGS "-DMODEL_${MODEL}")
|
||||
|
||||
set(OPTIM_FLAGS "-Os -flto -finline-small-functions -findirect-inlining -fdiagnostics-color -ffunction-sections -fdata-sections -fshort-enums -fsingle-precision-constant -ffreestanding -fno-common")
|
||||
|
||||
message(ERROR "flags >${CORE_FLAGS}<")
|
||||
# compiler: language specific flags
|
||||
set(CMAKE_C_FLAGS " ${CORE_FLAGS} ${OPTIM_FLAGS} ${TARGET_FLAGS} -fno-builtin -Wall -std=gnu11 -fdata-sections -ffunction-sections -g3 " CACHE INTERNAL "c compiler flags")
|
||||
set(CMAKE_CXX_FLAGS " ${CORE_FLAGS} ${OPTIM_FLAGS} ${TARGET_FLAGS} -fno-rtti -fno-exceptions -fno-builtin -Wall -std=gnu++11 -fdata-sections -ffunction-sections -g -ggdb3" CACHE INTERNAL "cxx compiler flags")
|
||||
set(CMAKE_ASM_FLAGS " ${CORE_FLAGS} ${OPTIM_FLAGS} ${TARGET_FLAGS} -g -ggdb3 -D__USES_CXX" CACHE INTERNAL "asm compiler flags")
|
||||
|
||||
# search for programs in the build host directories
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
|
||||
# for libraries and headers in the target directories
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
6
source/CMake/stm32f1.cmake
Normal file
6
source/CMake/stm32f1.cmake
Normal file
@@ -0,0 +1,6 @@
|
||||
# core flags
|
||||
|
||||
set(CORE_FLAGS "-mthumb -mcpu=cortex-m3 -mlittle-endian -mfloat-abi=soft" CACHE INTERNAL "CPU flags")
|
||||
add_definitions(${CORE_FLAGS})
|
||||
# link with linker file
|
||||
target_link_libraries(${elf_file} PUBLIC -T ${CMAKE_CURRENT_SOURCE_DIR}/linkers/stm32f103.ld)
|
||||
87
source/CMakeLists.txt
Normal file
87
source/CMakeLists.txt
Normal file
@@ -0,0 +1,87 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
set(application_name "${MODEL}_${LANG}")
|
||||
set(elf_file ${application_name}.elf)
|
||||
set(bin_file ${application_name}.bin)
|
||||
set(hex_file ${application_name}.hex)
|
||||
set(map_file ${application_name}.map)
|
||||
|
||||
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/CMake")
|
||||
|
||||
|
||||
|
||||
if (MODEL STREQUAL TS100 OR MODEL STREQUAL TS80 OR MODEL STREQUAL TS80P)
|
||||
set(CMAKE_TOOLCHAIN_FILE "CMake/arm-gcc.cmake" CACHE PATH "toolchain file")
|
||||
include(${CMAKE_TOOLCHAIN_FILE})
|
||||
elseif(MODEL STREQUAL Pinecil)
|
||||
set(CMAKE_TOOLCHAIN_FILE "CMake/riscv-gcc.cmake" CACHE PATH "toolchain file")
|
||||
include(${CMAKE_TOOLCHAIN_FILE})
|
||||
elseif(MODEL STREQUAL MHP30)
|
||||
set(CMAKE_TOOLCHAIN_FILE "CMake/arm-gcc.cmake" CACHE PATH "toolchain file")
|
||||
include(${CMAKE_TOOLCHAIN_FILE})
|
||||
else()
|
||||
message(FATAL_ERROR "You must specify a model")
|
||||
endif()
|
||||
|
||||
|
||||
# Export compile commands for IDE's
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
#add_compile_options( -Wall -Werror)
|
||||
|
||||
|
||||
project(IronOS
|
||||
LANGUAGES C CXX ASM
|
||||
)
|
||||
#Setup outputs
|
||||
|
||||
project (${application_name} C CXX ASM)
|
||||
|
||||
|
||||
# add sources to elf file
|
||||
|
||||
file(WRITE null.cpp "")
|
||||
|
||||
add_executable(${elf_file}
|
||||
null.cpp
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
include_directories(
|
||||
Core
|
||||
Middlewares
|
||||
)
|
||||
add_subdirectory(Core)
|
||||
add_subdirectory(Middlewares)
|
||||
|
||||
|
||||
|
||||
target_link_libraries(${elf_file} PRIVATE BSP mainSource threads FreeRTOS languages BSPImplementation drivers USBPDLib)
|
||||
|
||||
if (MODEL STREQUAL TS100 OR MODEL STREQUAL TS80 OR MODEL STREQUAL TS80P)
|
||||
include(stm32f1)
|
||||
elseif(MODEL STREQUAL Pinecil)
|
||||
include(gd32vf1)
|
||||
elseif(MODEL STREQUAL MHP30)
|
||||
include(stm32f1)
|
||||
else()
|
||||
message(FATAL_ERROR "You must specify a model")
|
||||
endif()
|
||||
include(shared-compiler-settings)
|
||||
|
||||
|
||||
# set additional for compiler and linker: optimization and generate map file
|
||||
set(additional_compiler_flags ${opt_level})
|
||||
set(additional_linker_flags -Wl,-Map=${map_file},--cref,--no-warn-mismatch)
|
||||
target_compile_options(${elf_file} PRIVATE ${additional_compiler_flags})
|
||||
target_link_libraries(${elf_file} PRIVATE ${additional_linker_flags})
|
||||
|
||||
# remove unused sections
|
||||
|
||||
|
||||
|
||||
# create binary and hex files
|
||||
add_custom_target(${hex_file} DEPENDS ${elf_file} COMMAND ${CMAKE_OBJCOPY} -O ihex ${elf_file} ${hex_file})
|
||||
add_custom_target(${bin_file} DEPENDS ${elf_file} COMMAND ${CMAKE_OBJCOPY} -O binary ${elf_file} ${bin_file})
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "BSP_Power.h"
|
||||
#include "BSP_QC.h"
|
||||
#include "Defines.h"
|
||||
#include "configuration.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
/*
|
||||
|
||||
20
source/Core/BSP/CMakeLists.txt
Normal file
20
source/Core/BSP/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(sources
|
||||
BSP_Common.c
|
||||
)
|
||||
|
||||
|
||||
add_library(BSP ${sources})
|
||||
target_include_directories(BSP PUBLIC .)
|
||||
target_link_libraries(BSP PUBLIC FreeRTOS)
|
||||
|
||||
if (MODEL STREQUAL TS100 OR MODEL STREQUAL TS80 OR MODEL STREQUAL TS80P)
|
||||
add_subdirectory(Miniware)
|
||||
elseif(MODEL STREQUAL Pinecil)
|
||||
add_subdirectory(Pine64)
|
||||
elseif(MODEL STREQUAL MHP30)
|
||||
add_subdirectory(MHP30)
|
||||
else()
|
||||
message(FATAL_ERROR "You must specify a model")
|
||||
endif()
|
||||
52
source/Core/BSP/Miniware/CMakeLists.txt
Normal file
52
source/Core/BSP/Miniware/CMakeLists.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Vendor/CMSIS/Include)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Vendor/CMSIS/Device)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Inc)
|
||||
set(sources
|
||||
BSP.cpp
|
||||
flash.c
|
||||
fusb_user.cpp
|
||||
I2C_Wrapper.cpp
|
||||
IRQ.cpp
|
||||
port.c
|
||||
postRTOS.cpp
|
||||
Power.cpp
|
||||
preRTOS.cpp
|
||||
QC_GPIO.cpp
|
||||
Setup.cpp
|
||||
startup_stm32f103t8ux.S
|
||||
stm32f1xx_hal_msp.c
|
||||
stm32f1xx_hal_timebase_TIM.c
|
||||
stm32f1xx_it.c
|
||||
system_stm32f1xx.c
|
||||
ThermoModel.cpp
|
||||
# ST code
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_iwdg.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
|
||||
)
|
||||
|
||||
|
||||
add_library(BSPImplementation ${sources})
|
||||
target_include_directories(BSPImplementation PUBLIC . ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/CMSIS/Include ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/CMSIS/Device ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/STM32F1xx_HAL_Driver/Inc)
|
||||
target_compile_definitions (BSPImplementation PUBLIC "-D STM32F103T8Ux -D STM32F1 -D STM32 -D USE_HAL_DRIVER -D STM32F103xB -D USE_RTOS_SYSTICK -D GCC_ARMCM3 -D ARM_MATH_CM3 -D STM32F10X_MD")
|
||||
target_link_libraries(BSPImplementation PUBLIC brieflz BSP mainSource drivers)
|
||||
|
||||
|
||||
target_link_libraries(${elf_file} PUBLIC -Wl,--defsym=__FLASH_SIZE__=64k -Wl,--defsym=__BOOTLDR_SIZE__=0x4000)
|
||||
|
||||
set(DEVICE_DFU_ADDRESS 0x08004000)
|
||||
set(DEVICE_DFU_VID_PID 0x1209:0xDB42)
|
||||
344
source/Core/BSP/Miniware/startup_stm32f103t8ux.S
Normal file
344
source/Core/BSP/Miniware/startup_stm32f103t8ux.S
Normal file
@@ -0,0 +1,344 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file startup_stm32.s
|
||||
* @author Ac6
|
||||
* @version V1.0.0
|
||||
* @date 12-June-2014
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m3
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
|
||||
.equ BootRAM, 0xF1E0F85F
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied main() routine is called.
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
movs r1, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r3, =_sidata
|
||||
ldr r3, [r3, r1]
|
||||
str r3, [r0, r1]
|
||||
adds r1, r1, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
ldr r0, =_sdata
|
||||
ldr r3, =_edata
|
||||
adds r2, r0, r1
|
||||
cmp r2, r3
|
||||
bcc CopyDataInit
|
||||
ldr r2, =_sbss
|
||||
b LoopFillZerobss
|
||||
/* Zero fill the bss segment. */
|
||||
FillZerobss:
|
||||
movs r3, #0
|
||||
str r3, [r2]
|
||||
adds r2, r2, #4
|
||||
|
||||
LoopFillZerobss:
|
||||
ldr r3, = _ebss
|
||||
cmp r2, r3
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call the clock system intitialization function.*/
|
||||
bl SystemInit
|
||||
/* Call static constructors */
|
||||
bl __libc_init_array
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
|
||||
LoopForever:
|
||||
b LoopForever
|
||||
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
*
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
/******************************************************************************
|
||||
*
|
||||
* The minimal vector table for a Cortex-M. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
.word WWDG_IRQHandler
|
||||
.word PVD_IRQHandler
|
||||
.word TAMPER_IRQHandler
|
||||
.word RTC_IRQHandler
|
||||
.word FLASH_IRQHandler
|
||||
.word RCC_IRQHandler
|
||||
.word EXTI0_IRQHandler
|
||||
.word EXTI1_IRQHandler
|
||||
.word EXTI2_IRQHandler
|
||||
.word EXTI3_IRQHandler
|
||||
.word EXTI4_IRQHandler
|
||||
.word DMA1_Channel1_IRQHandler
|
||||
.word DMA1_Channel2_IRQHandler
|
||||
.word DMA1_Channel3_IRQHandler
|
||||
.word DMA1_Channel4_IRQHandler
|
||||
.word DMA1_Channel5_IRQHandler
|
||||
.word DMA1_Channel6_IRQHandler
|
||||
.word DMA1_Channel7_IRQHandler
|
||||
.word ADC1_2_IRQHandler
|
||||
.word USB_HP_CAN1_TX_IRQHandler
|
||||
.word USB_LP_CAN1_RX0_IRQHandler
|
||||
.word CAN1_RX1_IRQHandler
|
||||
.word CAN1_SCE_IRQHandler
|
||||
.word EXTI9_5_IRQHandler
|
||||
.word TIM1_BRK_IRQHandler
|
||||
.word TIM1_UP_IRQHandler
|
||||
.word TIM1_TRG_COM_IRQHandler
|
||||
.word TIM1_CC_IRQHandler
|
||||
.word TIM2_IRQHandler
|
||||
.word TIM3_IRQHandler
|
||||
.word TIM4_IRQHandler
|
||||
.word I2C1_EV_IRQHandler
|
||||
.word I2C1_ER_IRQHandler
|
||||
.word I2C2_EV_IRQHandler
|
||||
.word I2C2_ER_IRQHandler
|
||||
.word SPI1_IRQHandler
|
||||
.word SPI2_IRQHandler
|
||||
.word USART1_IRQHandler
|
||||
.word USART2_IRQHandler
|
||||
.word USART3_IRQHandler
|
||||
.word EXTI15_10_IRQHandler
|
||||
.word RTC_Alarm_IRQHandler
|
||||
.word USBWakeUp_IRQHandler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word BootRAM /* @0x108. This is for boot in RAM mode for
|
||||
STM32F10x Medium Density devices. */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak MemManage_Handler
|
||||
.thumb_set MemManage_Handler,Default_Handler
|
||||
|
||||
.weak BusFault_Handler
|
||||
.thumb_set BusFault_Handler,Default_Handler
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.thumb_set UsageFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.thumb_set DebugMon_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak PVD_IRQHandler
|
||||
.thumb_set PVD_IRQHandler,Default_Handler
|
||||
|
||||
.weak TAMPER_IRQHandler
|
||||
.thumb_set TAMPER_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_IRQHandler
|
||||
.thumb_set RTC_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_IRQHandler
|
||||
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI1_IRQHandler
|
||||
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_IRQHandler
|
||||
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI3_IRQHandler
|
||||
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_IRQHandler
|
||||
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel1_IRQHandler
|
||||
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel2_IRQHandler
|
||||
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel3_IRQHandler
|
||||
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel4_IRQHandler
|
||||
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel5_IRQHandler
|
||||
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel6_IRQHandler
|
||||
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel7_IRQHandler
|
||||
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC1_2_IRQHandler
|
||||
.thumb_set ADC1_2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USB_HP_CAN1_TX_IRQHandler
|
||||
.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
|
||||
|
||||
.weak USB_LP_CAN1_RX0_IRQHandler
|
||||
.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_RX1_IRQHandler
|
||||
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_SCE_IRQHandler
|
||||
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI9_5_IRQHandler
|
||||
.thumb_set EXTI9_5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_IRQHandler
|
||||
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_UP_IRQHandler
|
||||
.thumb_set TIM1_UP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_TRG_COM_IRQHandler
|
||||
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM4_IRQHandler
|
||||
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_EV_IRQHandler
|
||||
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_ER_IRQHandler
|
||||
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART3_IRQHandler
|
||||
.thumb_set USART3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI15_10_IRQHandler
|
||||
.thumb_set EXTI15_10_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_Alarm_IRQHandler
|
||||
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
|
||||
|
||||
.weak USBWakeUp_IRQHandler
|
||||
.thumb_set USBWakeUp_IRQHandler,Default_Handler
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT Ac6 *****END OF FILE****/
|
||||
63
source/Core/BSP/Pine64/CMakeLists.txt
Normal file
63
source/Core/BSP/Pine64/CMakeLists.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Vendor/NMSIS/Core/Include)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Vendor/OS/FreeRTOS/Source/portable/GCC)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Include)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Stubs/)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Stubs/)
|
||||
|
||||
|
||||
set(sources
|
||||
# Vendor Code
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/OS/FreeRTOS/Source/portable/GCC/portasm.S
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/OS/FreeRTOS/Source/portable/GCC/port.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/gd32vf103_soc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_adc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_bkp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_crc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dac.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dbg.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_dma.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_eclic.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exmc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_exti.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fmc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_fwdgt.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_gpio.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_i2c.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_pmu.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rcu.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_rtc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_spi.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_timer.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_usart.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/gd32vf103_wwdgt.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Drivers/n200_func.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/GCC/intexc_gd32vf103.S
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/GCC/startup_gd32vf103.S
|
||||
|
||||
BSP.cpp
|
||||
Debug.cpp
|
||||
I2C_Wrapper.cpp
|
||||
postRTOS.cpp
|
||||
preRTOS.cpp
|
||||
flash.c
|
||||
fusb_user.cpp
|
||||
ThermoModel.cpp
|
||||
IRQ.cpp
|
||||
Setup.cpp
|
||||
Power.cpp
|
||||
QC_GPIO.cpp
|
||||
)
|
||||
|
||||
|
||||
add_library(BSPImplementation ${sources})
|
||||
target_include_directories(BSPImplementation PUBLIC . ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/NMSIS/Core/Include ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/OS/FreeRTOS/Source/portable/GCC ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Include ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Stubs/ ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/SoC/gd32vf103/Common/Source/Stubs/)
|
||||
target_compile_definitions (BSPImplementation PUBLIC -DRTOS_FREERTOS -DDOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP -DUSE_RTOS_SYSTICK -DVECT_TAB_OFFSET=0U)
|
||||
target_link_libraries(BSPImplementation PRIVATE brieflz BSP threads drivers mainSource)
|
||||
|
||||
|
||||
target_link_libraries(${elf_file} PUBLIC -Wl,--defsym=__FLASH_SIZE__=128k -Wl,--defsym=__BOOTLDR_SIZE__=0)
|
||||
|
||||
set(DEVICE_DFU_ADDRESS 0x08000000)
|
||||
set(DEVICE_DFU_VID_PID 0x28E9:0x0189)
|
||||
@@ -2,10 +2,12 @@
|
||||
#define FREERTOS_CONFIG_H
|
||||
#include "nuclei_sdk_soc.h"
|
||||
#include <stdint.h>
|
||||
#define configISR_STACK_SIZE_WORDS 1024
|
||||
#define configCLINT_BASE_ADDRESS 0
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_TICKLESS_IDLE 0
|
||||
#define configCPU_CLOCK_HZ ((uint32_t)SystemCoreClock)
|
||||
#define configCPU_CLOCK_HZ (108000000U / 4)
|
||||
#define configRTC_CLOCK_HZ ((uint32_t)32768)
|
||||
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||
#define configMAX_PRIORITIES (4)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "IRQ.h"
|
||||
#include "Pins.h"
|
||||
#include "configuration.h"
|
||||
#include "main.hpp"
|
||||
volatile uint8_t i2c_read_process = 0;
|
||||
volatile uint8_t i2c_write_process = 0;
|
||||
volatile uint8_t i2c_slave_address = 0;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef __FREERTOS_RISC_V_EXTENSIONS_H__
|
||||
#define __FREERTOS_RISC_V_EXTENSIONS_H__
|
||||
|
||||
#define portasmHAS_CLINT 0
|
||||
#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */
|
||||
|
||||
.macro portasmSAVE_ADDITIONAL_REGISTERS
|
||||
/* No additional registers to save, so this macro does nothing. */
|
||||
.endm
|
||||
|
||||
/* Restore the additional registers found on the Pulpino. */
|
||||
.macro portasmRESTORE_ADDITIONAL_REGISTERS
|
||||
/* No additional registers to restore, so this macro does nothing. */
|
||||
.endm
|
||||
|
||||
/* hkim temporary workaround */
|
||||
#define portasmMCAUSE_MASK 0xfff
|
||||
#define portasmHANDLE_INTERRUPT irq_entry
|
||||
#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */
|
||||
@@ -26,55 +26,18 @@
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the Nuclei N/NX Processor port.
|
||||
* Implementation of functions defined in portable.h for the RISC-V RV32 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "portmacro.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
|
||||
//#define ENABLE_KERNEL_DEBUG
|
||||
|
||||
#ifdef ENABLE_KERNEL_DEBUG
|
||||
#define FREERTOS_PORT_DEBUG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define FREERTOS_PORT_DEBUG(...)
|
||||
#ifndef configCLINT_BASE_ADDRESS
|
||||
#warning configCLINT_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a Core Local Interrupter (CLINT) then set configCLINT_BASE_ADDRESS to the CLINT base address. Otherwise set configCLINT_BASE_ADDRESS to 0.
|
||||
#endif
|
||||
|
||||
#ifndef configSYSTICK_CLOCK_HZ
|
||||
#define configSYSTICK_CLOCK_HZ SOC_TIMER_FREQ
|
||||
#endif
|
||||
|
||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 0
|
||||
#endif
|
||||
|
||||
#ifndef configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
// See function prvCheckMaxSysCallPrio and prvCalcMaxSysCallMTH
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 255
|
||||
#endif
|
||||
|
||||
/* Constants required to check the validity of an interrupt priority. */
|
||||
#define portFIRST_USER_INTERRUPT_NUMBER (18)
|
||||
|
||||
#define SYSTICK_TICK_CONST (configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ)
|
||||
|
||||
/* Masks off all bits but the ECLIC MTH bits in the MTH register. */
|
||||
#define portMTH_MASK (0xFFUL)
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_MSTATUS (MSTATUS_MPP | MSTATUS_MPIE | MSTATUS_FS_INITIAL)
|
||||
#define portINITIAL_EXC_RETURN (0xfffffffd)
|
||||
|
||||
/* The systick is a 64-bit counter. */
|
||||
#define portMAX_BIT_NUMBER (SysTimer_MTIMER_Msk)
|
||||
|
||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||
occurred while the SysTick counter is stopped during tickless idle
|
||||
calculations. */
|
||||
#define portMISSED_COUNTS_FACTOR (45UL)
|
||||
|
||||
/* Let the user override the pre-loading of the initial LR with the address of
|
||||
prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||
debugger. */
|
||||
@@ -84,574 +47,145 @@ debugger. */
|
||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#endif
|
||||
|
||||
/* The stack used by interrupt service routines. Set configISR_STACK_SIZE_WORDS
|
||||
to use a statically allocated array as the interrupt stack. Alternative leave
|
||||
configISR_STACK_SIZE_WORDS undefined and update the linker script so that a
|
||||
linker variable names __freertos_irq_stack_top has the same value as the top
|
||||
of the stack used by main. Using the linker script method will repurpose the
|
||||
stack that was used by main before the scheduler was started for use as the
|
||||
interrupt stack after the scheduler has started. */
|
||||
#ifdef configISR_STACK_SIZE_WORDS
|
||||
static __attribute__((aligned(16))) StackType_t xISRStack[configISR_STACK_SIZE_WORDS] = {0};
|
||||
const StackType_t xISRStackTop = (StackType_t) & (xISRStack[(configISR_STACK_SIZE_WORDS & ~portBYTE_ALIGNMENT_MASK) - 1]);
|
||||
#else
|
||||
extern const uint32_t __freertos_irq_stack_top[];
|
||||
const StackType_t xISRStackTop = (StackType_t)__freertos_irq_stack_top;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the timer to generate the tick interrupts. The implementation in this
|
||||
* file is weak to allow application writers to change the timer used to
|
||||
* generate the tick interrupt.
|
||||
*/
|
||||
void vPortSetupTimerInterrupt(void);
|
||||
|
||||
/*
|
||||
* Exception handlers.
|
||||
*/
|
||||
void xPortSysTickHandler(void);
|
||||
|
||||
/*
|
||||
* Start first task is a separate function so it can be tested in isolation.
|
||||
*/
|
||||
extern void prvPortStartFirstTask(void) __attribute__((naked));
|
||||
|
||||
/*
|
||||
* Used to catch tasks that attempt to return from their implementing function.
|
||||
*/
|
||||
static void prvTaskExitError(void);
|
||||
|
||||
#define xPortSysTickHandler eclic_mtip_handler
|
||||
void vPortSetupTimerInterrupt(void) __attribute__((weak));
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
/* Used to program the machine timer compare register. */
|
||||
uint64_t ullNextTime = 0ULL;
|
||||
const uint64_t *pullNextTime = &ullNextTime;
|
||||
const size_t uxTimerIncrementsForOneTick = (size_t)(configCPU_CLOCK_HZ / configTICK_RATE_HZ); /* Assumes increment won't go over 32-bits. */
|
||||
volatile uint64_t *const pullMachineTimerCompareRegister = (volatile uint64_t *const)(configCLINT_BASE_ADDRESS + 0x4000);
|
||||
|
||||
/*
|
||||
* Record the real MTH calculated by the configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
* The configMAX_SYSCALL_INTERRUPT_PRIORITY is not the left-aligned level value,
|
||||
* See equations below:
|
||||
* Level Bits number: lvlbits = min(nlbits, CLICINTCTLBITS)
|
||||
* Left align Bits number: lfabits = 8-lvlbits
|
||||
* 0 < configMAX_SYSCALL_INTERRUPT_PRIORITY <= (2^lvlbits-1)
|
||||
* uxMaxSysCallMTH = (configMAX_SYSCALL_INTERRUPT_PRIORITY << lfabits) | ((2^lfabits)-1)
|
||||
* If nlbits = 3, CLICINTCTLBITS=3, then lvlbits = 3, lfabits = 5
|
||||
* Set configMAX_SYSCALL_INTERRUPT_PRIORITY to 6
|
||||
* Then uxMaxSysCallMTH = (6<<5) | (2^5 - 1) = 223
|
||||
*
|
||||
* See function prvCheckMaxSysCallPrio and prvCalcMaxSysCallMTH
|
||||
*/
|
||||
uint8_t uxMaxSysCallMTH = 255;
|
||||
/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task
|
||||
stack checking. A problem in the ISR stack will trigger an assert, not call the
|
||||
stack overflow hook function (because the stack overflow hook is specific to a
|
||||
task stack, not the ISR stack). */
|
||||
#if (configCHECK_FOR_STACK_OVERFLOW > 2)
|
||||
#warning This path not tested, or even compiled yet.
|
||||
/* Don't use 0xa5 as the stack fill bytes as that is used by the kernerl for
|
||||
the task stacks, and so will legitimately appear in many positions within
|
||||
the ISR stack. */
|
||||
#define portISR_STACK_FILL_BYTE 0xee
|
||||
|
||||
/*
|
||||
* The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
#if (configUSE_TICKLESS_IDLE == 1)
|
||||
static TickType_t ulTimerCountsForOneTick = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
static const uint8_t ucExpectedStackBytes[]
|
||||
= {portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE,
|
||||
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE,
|
||||
portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE, portISR_STACK_FILL_BYTE};
|
||||
|
||||
/*
|
||||
* The maximum number of tick periods that can be suppressed is limited by the
|
||||
* 24 bit resolution of the SysTick timer.
|
||||
*/
|
||||
#if (configUSE_TICKLESS_IDLE == 1)
|
||||
static TickType_t xMaximumPossibleSuppressedTicks = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||
* power functionality only.
|
||||
*/
|
||||
#if (configUSE_TICKLESS_IDLE == 1)
|
||||
static TickType_t ulStoppedTimerCompensation = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*/
|
||||
#if (configASSERT_DEFINED == 1)
|
||||
static uint8_t ucMaxSysCallPriority = 0;
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
* As per the standard RISC-V ABI pxTopcOfStack is passed in in a0, pxCode in
|
||||
* a1, and pvParameters in a2. The new top of stack is passed out in a0.
|
||||
*
|
||||
* RISC-V maps registers to ABI names as follows (X1 to X31 integer registers
|
||||
* for the 'I' profile, X1 to X15 for the 'E' profile, currently I assumed).
|
||||
*
|
||||
* Register ABI Name Description Saver
|
||||
* x0 zero Hard-wired zero -
|
||||
* x1 ra Return address Caller
|
||||
* x2 sp Stack pointer Callee
|
||||
* x3 gp Global pointer -
|
||||
* x4 tp Thread pointer -
|
||||
* x5-7 t0-2 Temporaries Caller
|
||||
* x8 s0/fp Saved register/Frame pointer Callee
|
||||
* x9 s1 Saved register Callee
|
||||
* x10-11 a0-1 Function Arguments/return values Caller
|
||||
* x12-17 a2-7 Function arguments Caller
|
||||
* x18-27 s2-11 Saved registers Callee
|
||||
* x28-31 t3-6 Temporaries Caller
|
||||
*
|
||||
* The RISC-V context is saved RTOS tasks in the following stack frame,
|
||||
* where the global and thread pointers are currently assumed to be constant so
|
||||
* are not saved:
|
||||
*
|
||||
* mstatus
|
||||
* #ifndef __riscv_32e
|
||||
* x31
|
||||
* x30
|
||||
* x29
|
||||
* x28
|
||||
* x27
|
||||
* x26
|
||||
* x25
|
||||
* x24
|
||||
* x23
|
||||
* x22
|
||||
* x21
|
||||
* x20
|
||||
* x19
|
||||
* x18
|
||||
* x17
|
||||
* x16
|
||||
* #endif
|
||||
* x15
|
||||
* x14
|
||||
* x13
|
||||
* x12
|
||||
* x11
|
||||
* pvParameters
|
||||
* x9
|
||||
* x8
|
||||
* x7
|
||||
* x6
|
||||
* x5
|
||||
* portTASK_RETURN_ADDRESS
|
||||
* pxCode
|
||||
*/
|
||||
StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) {
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
interrupt. */
|
||||
|
||||
/* Offset added to account for the way the MCU uses the stack on entry/exit
|
||||
of interrupts, and to ensure alignment. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portINITIAL_MSTATUS; /* MSTATUS */
|
||||
|
||||
/* Save code space by skipping register initialisation. */
|
||||
#ifndef __riscv_32e
|
||||
pxTopOfStack -= 22; /* X11 - X31. */
|
||||
#define portCHECK_ISR_STACK() configASSERT((memcmp((void *)xISRStack, (void *)ucExpectedStackBytes, sizeof(ucExpectedStackBytes)) == 0))
|
||||
#else
|
||||
pxTopOfStack -= 6; /* X11 - X15. */
|
||||
#endif
|
||||
*pxTopOfStack = (StackType_t)pvParameters; /* X10/A0 */
|
||||
pxTopOfStack -= 6; /* X5 - X9 */
|
||||
*pxTopOfStack = (StackType_t)portTASK_RETURN_ADDRESS; /* RA, X1 */
|
||||
/* Define the function away. */
|
||||
#define portCHECK_ISR_STACK()
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ((StackType_t)pxCode); /* PC */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTaskExitError(void) {
|
||||
volatile uint32_t ulDummy = 0;
|
||||
#if (configCLINT_BASE_ADDRESS != 0)
|
||||
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
its caller as there is nothing to return to. If a task wants to exit it
|
||||
should instead call vTaskDelete( NULL ).
|
||||
void vPortSetupTimerInterrupt(void) {
|
||||
uint32_t ulCurrentTimeHigh, ulCurrentTimeLow;
|
||||
volatile uint32_t *const pulTimeHigh = (volatile uint32_t *const)(configCLINT_BASE_ADDRESS + 0xBFFC);
|
||||
volatile uint32_t *const pulTimeLow = (volatile uint32_t *const)(configCLINT_BASE_ADDRESS + 0xBFF8);
|
||||
|
||||
Artificially force an assert() to be triggered if configASSERT() is
|
||||
defined, then stop here so application writers can catch the error. */
|
||||
configASSERT(uxCriticalNesting == ~0UL);
|
||||
portDISABLE_INTERRUPTS();
|
||||
while (ulDummy == 0) {
|
||||
/* This file calls prvTaskExitError() after the scheduler has been
|
||||
started to remove a compiler warning about the function being defined
|
||||
but never called. ulDummy is used purely to quieten other warnings
|
||||
about code appearing after this function is called - making ulDummy
|
||||
volatile makes the compiler think the function could return and
|
||||
therefore not output an 'unreachable code' warning for code that appears
|
||||
after it. */
|
||||
/* Sleep and wait for interrupt */
|
||||
__WFI();
|
||||
}
|
||||
do {
|
||||
ulCurrentTimeHigh = *pulTimeHigh;
|
||||
ulCurrentTimeLow = *pulTimeLow;
|
||||
} while (ulCurrentTimeHigh != *pulTimeHigh);
|
||||
|
||||
ullNextTime = (uint64_t)ulCurrentTimeHigh;
|
||||
ullNextTime <<= 32ULL;
|
||||
ullNextTime |= (uint64_t)ulCurrentTimeLow;
|
||||
ullNextTime += (uint64_t)uxTimerIncrementsForOneTick;
|
||||
*pullMachineTimerCompareRegister = ullNextTime;
|
||||
|
||||
/* Prepare the time to use after the next tick interrupt. */
|
||||
ullNextTime += (uint64_t)uxTimerIncrementsForOneTick;
|
||||
}
|
||||
|
||||
#endif /* ( configCLINT_BASE_ADDRESS != 0 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static uint8_t prvCheckMaxSysCallPrio(uint8_t max_syscall_prio) {
|
||||
uint8_t nlbits = __ECLIC_GetCfgNlbits();
|
||||
uint8_t intctlbits = __ECLIC_INTCTLBITS;
|
||||
uint8_t lvlbits, temp;
|
||||
|
||||
if (nlbits <= intctlbits) {
|
||||
lvlbits = nlbits;
|
||||
} else {
|
||||
lvlbits = intctlbits;
|
||||
}
|
||||
|
||||
temp = ((1 << lvlbits) - 1);
|
||||
if (max_syscall_prio > temp) {
|
||||
max_syscall_prio = temp;
|
||||
}
|
||||
return max_syscall_prio;
|
||||
}
|
||||
|
||||
static uint8_t prvCalcMaxSysCallMTH(uint8_t max_syscall_prio) {
|
||||
uint8_t nlbits = __ECLIC_GetCfgNlbits();
|
||||
uint8_t intctlbits = __ECLIC_INTCTLBITS;
|
||||
uint8_t lvlbits, lfabits;
|
||||
uint8_t maxsyscallmth = 0;
|
||||
uint8_t temp;
|
||||
|
||||
if (nlbits <= intctlbits) {
|
||||
lvlbits = nlbits;
|
||||
} else {
|
||||
lvlbits = intctlbits;
|
||||
}
|
||||
|
||||
lfabits = 8 - lvlbits;
|
||||
|
||||
temp = ((1 << lvlbits) - 1);
|
||||
if (max_syscall_prio > temp) {
|
||||
max_syscall_prio = temp;
|
||||
}
|
||||
|
||||
maxsyscallmth = (max_syscall_prio << lfabits) | ((1 << lfabits) - 1);
|
||||
|
||||
return maxsyscallmth;
|
||||
}
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler(void) {
|
||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. */
|
||||
configASSERT(configMAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
|
||||
/* Get the real MTH should be set to ECLIC MTH register */
|
||||
uxMaxSysCallMTH = prvCalcMaxSysCallMTH(configMAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
FREERTOS_PORT_DEBUG("Max SysCall MTH is set to 0x%x\n", uxMaxSysCallMTH);
|
||||
extern void xPortStartFirstTask(void);
|
||||
|
||||
#if (configASSERT_DEFINED == 1)
|
||||
{
|
||||
/* Use the same mask on the maximum system call priority. */
|
||||
ucMaxSysCallPriority = prvCheckMaxSysCallPrio(configMAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
FREERTOS_PORT_DEBUG("Max SysCall Priority is set to %d\n", ucMaxSysCallPriority);
|
||||
}
|
||||
#endif /* conifgASSERT_DEFINED */
|
||||
volatile uint32_t mtvec = 0;
|
||||
|
||||
__disable_irq();
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
/* Check the least significant two bits of mtvec are 00 - indicating
|
||||
single vector mode. */
|
||||
__asm volatile("csrr %0, mtvec" : "=r"(mtvec));
|
||||
configASSERT((mtvec & 0x03UL) == 0);
|
||||
|
||||
/* Check alignment of the interrupt stack - which is the same as the
|
||||
stack that was being used by main() prior to the scheduler being
|
||||
started. */
|
||||
configASSERT((xISRStackTop & portBYTE_ALIGNMENT_MASK) == 0);
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* If there is a CLINT then it is ok to use the default implementation
|
||||
in this file, otherwise vPortSetupTimerInterrupt() must be implemented to
|
||||
configure whichever clock is to be used to generate the tick interrupt. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
uxCriticalNesting = 0;
|
||||
#if (configCLINT_BASE_ADDRESS != 0)
|
||||
{
|
||||
/* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11
|
||||
for external interrupt. _RB_ What happens here when mtime is not present as
|
||||
with pulpino? */
|
||||
__asm volatile("csrs mie, %0" ::"r"(0x880));
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* Enable external interrupts. */
|
||||
__asm volatile("csrs mie, %0" ::"r"(0x800));
|
||||
}
|
||||
#endif /* configCLINT_BASE_ADDRESS */
|
||||
|
||||
/* Start the first task. */
|
||||
prvPortStartFirstTask();
|
||||
xPortStartFirstTask();
|
||||
|
||||
/* Should never get here as the tasks will now be executing! Call the task
|
||||
exit error function to prevent compiler warnings about a static function
|
||||
not being called in the case that the application writer overrides this
|
||||
functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||
vTaskSwitchContext() so link time optimisation does not remove the
|
||||
symbol. */
|
||||
vTaskSwitchContext();
|
||||
prvTaskExitError();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
/* Should not get here as after calling xPortStartFirstTask() only tasks
|
||||
should be executing. */
|
||||
return pdFAIL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler(void) {
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
Artificially force an assert. */
|
||||
configASSERT(uxCriticalNesting == 1000UL);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical(void) {
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
assert() if it is being called from an interrupt context. Only API
|
||||
functions that end in "FromISR" can be used in an interrupt. Only assert if
|
||||
the critical nesting count is 1 to protect against recursive calls if the
|
||||
assert function also uses a critical section. */
|
||||
if (uxCriticalNesting == 1) {
|
||||
configASSERT((__ECLIC_GetMth() & portMTH_MASK) == uxMaxSysCallMTH);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical(void) {
|
||||
configASSERT(uxCriticalNesting);
|
||||
uxCriticalNesting--;
|
||||
if (uxCriticalNesting == 0) {
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortAssert(int32_t x) {
|
||||
TaskHandle_t th;
|
||||
if ((x) == 0) {
|
||||
taskDISABLE_INTERRUPTS();
|
||||
#if (INCLUDE_xTaskGetCurrentTaskHandle == 1)
|
||||
th = xTaskGetCurrentTaskHandle();
|
||||
if (th) {
|
||||
printf("Assert in task %s\n", pcTaskGetName(th));
|
||||
}
|
||||
#endif
|
||||
while (1) {
|
||||
/* Sleep and wait for interrupt */
|
||||
__WFI();
|
||||
};
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void xPortTaskSwitch(void) {
|
||||
portDISABLE_INTERRUPTS();
|
||||
/* Clear Software IRQ, A MUST */
|
||||
SysTimer_ClearSWIRQ();
|
||||
vTaskSwitchContext();
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void xPortSysTickHandler(void) {
|
||||
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
|
||||
executes all interrupts must be unmasked. There is therefore no need to
|
||||
save and then restore the interrupt mask value as its value is already
|
||||
known. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
{
|
||||
SysTick_Reload(SYSTICK_TICK_CONST);
|
||||
/* Increment the RTOS tick. */
|
||||
if (xTaskIncrementTick() != pdFALSE) {
|
||||
/* A context switch is required. Context switching is performed in
|
||||
the SWI interrupt. Pend the SWI interrupt. */
|
||||
portYIELD();
|
||||
}
|
||||
}
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if (configUSE_TICKLESS_IDLE == 1)
|
||||
|
||||
__attribute__((weak)) void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) {
|
||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||
volatile TickType_t xModifiableIdleTime, xTickCountBeforeSleep, XLastLoadValue;
|
||||
|
||||
FREERTOS_PORT_DEBUG("Enter TickLess %d\n", (uint32_t)xExpectedIdleTime);
|
||||
|
||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||
if (xExpectedIdleTime > xMaximumPossibleSuppressedTicks) {
|
||||
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
||||
/* Not implemented. */
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
||||
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
||||
is accounted for as best it can be, but using the tickless mode will
|
||||
inevitably result in some tiny drift of the time maintained by the
|
||||
kernel with respect to calendar time. */
|
||||
SysTimer_Stop();
|
||||
void irq_entry(uint32_t mcause) {
|
||||
uint32_t ulInterruptNumber;
|
||||
typedef void (*irq_handler_t)(void);
|
||||
extern const irq_handler_t vector_base[];
|
||||
|
||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||
tick periods. -1 is used because this code will execute part way
|
||||
through one of the tick periods. */
|
||||
ulReloadValue = (ulTimerCountsForOneTick * (xExpectedIdleTime - 1UL));
|
||||
if (ulReloadValue > ulStoppedTimerCompensation) {
|
||||
ulReloadValue -= ulStoppedTimerCompensation;
|
||||
}
|
||||
ulInterruptNumber = mcause & 0xFFF;
|
||||
|
||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||
method as that will mask interrupts that should exit sleep mode. */
|
||||
__disable_irq();
|
||||
|
||||
/* If a context switch is pending or a task is waiting for the scheduler
|
||||
to be unsuspended then abandon the low power entry. */
|
||||
if (eTaskConfirmSleepModeStatus() == eAbortSleep) {
|
||||
/* Restart from whatever is left in the count register to complete
|
||||
this tick period. */
|
||||
/* Restart SysTick. */
|
||||
SysTimer_Start();
|
||||
|
||||
/* Reset the reload register to the value required for normal tick
|
||||
periods. */
|
||||
SysTick_Reload(ulTimerCountsForOneTick);
|
||||
|
||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||
above. */
|
||||
__enable_irq();
|
||||
} else {
|
||||
xTickCountBeforeSleep = xTaskGetTickCount();
|
||||
|
||||
/* Set the new reload value. */
|
||||
SysTick_Reload(ulReloadValue);
|
||||
|
||||
/* Get System timer load value before sleep */
|
||||
XLastLoadValue = SysTimer_GetLoadValue();
|
||||
|
||||
/* Restart SysTick. */
|
||||
SysTimer_Start();
|
||||
ECLIC_EnableIRQ(SysTimer_IRQn);
|
||||
__RWMB();
|
||||
|
||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||
set its parameter to 0 to indicate that its implementation contains
|
||||
its own wait for interrupt or wait for event instruction, and so wfi
|
||||
should not be executed again. However, the original expected idle
|
||||
time variable must remain unmodified, so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING(xModifiableIdleTime);
|
||||
if (xModifiableIdleTime > 0) {
|
||||
__WFI();
|
||||
}
|
||||
configPOST_SLEEP_PROCESSING(xExpectedIdleTime);
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
out of sleep mode to execute immediately. */
|
||||
__enable_irq();
|
||||
|
||||
/* Make sure interrupt enable is executed */
|
||||
__RWMB();
|
||||
__FENCE_I();
|
||||
__NOP();
|
||||
|
||||
/* Disable interrupts again because the clock is about to be stopped
|
||||
and interrupts that execute while the clock is stopped will increase
|
||||
any slippage between the time maintained by the RTOS and calendar
|
||||
time. */
|
||||
__disable_irq();
|
||||
|
||||
/* Disable the SysTick clock. Again,
|
||||
the time the SysTick is stopped for is accounted for as best it can
|
||||
be, but using the tickless mode will inevitably result in some tiny
|
||||
drift of the time maintained by the kernel with respect to calendar
|
||||
time*/
|
||||
ECLIC_DisableIRQ(SysTimer_IRQn);
|
||||
|
||||
/* Determine if SysTimer Interrupt is not yet happened,
|
||||
(in which case an interrupt other than the SysTick
|
||||
must have brought the system out of sleep mode). */
|
||||
if (SysTimer_GetLoadValue() >= (XLastLoadValue + ulReloadValue)) {
|
||||
/* As the pending tick will be processed as soon as this
|
||||
function exits, the tick value maintained by the tick is stepped
|
||||
forward by one less than the time spent waiting. */
|
||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||
FREERTOS_PORT_DEBUG("TickLess - SysTimer Interrupt Entered!\n");
|
||||
} else {
|
||||
/* Something other than the tick interrupt ended the sleep.
|
||||
Work out how long the sleep lasted rounded to complete tick
|
||||
periods (not the ulReload value which accounted for part
|
||||
ticks). */
|
||||
xModifiableIdleTime = SysTimer_GetLoadValue();
|
||||
if (xModifiableIdleTime > XLastLoadValue) {
|
||||
ulCompletedSysTickDecrements = (xModifiableIdleTime - XLastLoadValue);
|
||||
} else {
|
||||
ulCompletedSysTickDecrements = (xModifiableIdleTime + portMAX_BIT_NUMBER - XLastLoadValue);
|
||||
}
|
||||
|
||||
/* How many complete tick periods passed while the processor
|
||||
was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
period remains. */
|
||||
SysTick_Reload(ulTimerCountsForOneTick);
|
||||
FREERTOS_PORT_DEBUG("TickLess - External Interrupt Happened!\n");
|
||||
}
|
||||
|
||||
FREERTOS_PORT_DEBUG("End TickLess %d\n", (uint32_t)ulCompleteTickPeriods);
|
||||
|
||||
/* Restart SysTick */
|
||||
vTaskStepTick(ulCompleteTickPeriods);
|
||||
|
||||
/* Exit with interrupts enabled. */
|
||||
ECLIC_EnableIRQ(SysTimer_IRQn);
|
||||
__enable_irq();
|
||||
if (vector_base[ulInterruptNumber]) {
|
||||
vector_base[ulInterruptNumber]();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if configUSE_TICKLESS_IDLE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the systick timer to generate the tick interrupts at the required
|
||||
* frequency.
|
||||
*/
|
||||
__attribute__((weak)) void vPortSetupTimerInterrupt(void) {
|
||||
/* Calculate the constants required to configure the tick interrupt. */
|
||||
#if (configUSE_TICKLESS_IDLE == 1)
|
||||
{
|
||||
ulTimerCountsForOneTick = (SYSTICK_TICK_CONST);
|
||||
xMaximumPossibleSuppressedTicks = portMAX_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / (configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ);
|
||||
FREERTOS_PORT_DEBUG("CountsForOneTick, SuppressedTicks and TimerCompensation: %u, %u, %u\n", (uint32_t)ulTimerCountsForOneTick, (uint32_t)xMaximumPossibleSuppressedTicks,
|
||||
(uint32_t)ulStoppedTimerCompensation);
|
||||
}
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
TickType_t ticks = SYSTICK_TICK_CONST;
|
||||
|
||||
/* Make SWI and SysTick the lowest priority interrupts. */
|
||||
/* Stop and clear the SysTimer. SysTimer as Non-Vector Interrupt */
|
||||
SysTick_Config(ticks);
|
||||
ECLIC_DisableIRQ(SysTimer_IRQn);
|
||||
ECLIC_SetLevelIRQ(SysTimer_IRQn, configKERNEL_INTERRUPT_PRIORITY);
|
||||
ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
|
||||
ECLIC_EnableIRQ(SysTimer_IRQn);
|
||||
|
||||
/* Set SWI interrupt level to lowest level/priority, SysTimerSW as Vector Interrupt */
|
||||
ECLIC_SetShvIRQ(SysTimerSW_IRQn, ECLIC_VECTOR_INTERRUPT);
|
||||
ECLIC_SetLevelIRQ(SysTimerSW_IRQn, configKERNEL_INTERRUPT_PRIORITY);
|
||||
ECLIC_EnableIRQ(SysTimerSW_IRQn);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if (configASSERT_DEFINED == 1)
|
||||
|
||||
void vPortValidateInterruptPriority(void) {
|
||||
uint32_t ulCurrentInterrupt;
|
||||
uint8_t ucCurrentPriority;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
CSR_MCAUSE_Type mcause = (CSR_MCAUSE_Type)__RV_CSR_READ(CSR_MCAUSE);
|
||||
/* Make sure current trap type is interrupt */
|
||||
configASSERT(mcause.b.interrupt == 1);
|
||||
if (mcause.b.interrupt) {
|
||||
ulCurrentInterrupt = mcause.b.exccode;
|
||||
/* Is the interrupt number a user defined interrupt? */
|
||||
if (ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER) {
|
||||
/* Look up the interrupt's priority. */
|
||||
ucCurrentPriority = __ECLIC_GetLevelIRQ(ulCurrentInterrupt);
|
||||
/* The following assertion will fail if a service routine (ISR) for
|
||||
an interrupt that has been assigned a priority above
|
||||
ucMaxSysCallPriority calls an ISR safe FreeRTOS API
|
||||
function. ISR safe FreeRTOS API functions must *only* be called
|
||||
from interrupts that have been assigned a priority at or below
|
||||
ucMaxSysCallPriority.
|
||||
|
||||
Numerically low interrupt priority numbers represent logically high
|
||||
interrupt priorities, therefore the priority of the interrupt must
|
||||
be set to a value equal to or numerically *higher* than
|
||||
ucMaxSysCallPriority.
|
||||
|
||||
Interrupts that use the FreeRTOS API must not be left at their
|
||||
default priority of zero as that is the highest possible priority,
|
||||
which is guaranteed to be above ucMaxSysCallPriority,
|
||||
and therefore also guaranteed to be invalid.
|
||||
|
||||
FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
interrupt entry is as fast and simple as possible.
|
||||
|
||||
The following links provide detailed information:
|
||||
http://www.freertos.org/FAQHelp.html */
|
||||
configASSERT(ucCurrentPriority <= ucMaxSysCallPriority);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* FreeRTOS Kernel V10.2.1
|
||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
@@ -26,377 +25,402 @@
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
#ifndef __riscv_32e
|
||||
#define portRegNum 30
|
||||
/*
|
||||
* The FreeRTOS kernel's RISC-V port is split between the the code that is
|
||||
* common across all currently supported RISC-V chips (implementations of the
|
||||
* RISC-V ISA), and code which tailors the port to a specific RISC-V chip:
|
||||
*
|
||||
* + The code that is common to all RISC-V chips is implemented in
|
||||
* FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S. There is only one
|
||||
* portASM.S file because the same file is used no matter which RISC-V chip is
|
||||
* in use.
|
||||
*
|
||||
* + The code that tailors the kernel's RISC-V port to a specific RISC-V
|
||||
* chip is implemented in freertos_risc_v_chip_specific_extensions.h. There
|
||||
* is one freertos_risc_v_chip_specific_extensions.h that can be used with any
|
||||
* RISC-V chip that both includes a standard CLINT and does not add to the
|
||||
* base set of RISC-V registers. There are additional
|
||||
* freertos_risc_v_chip_specific_extensions.h files for RISC-V implementations
|
||||
* that do not include a standard CLINT or do add to the base set of RISC-V
|
||||
* registers.
|
||||
*
|
||||
* CARE MUST BE TAKEN TO INCLDUE THE CORRECT
|
||||
* freertos_risc_v_chip_specific_extensions.h HEADER FILE FOR THE CHIP
|
||||
* IN USE. To include the correct freertos_risc_v_chip_specific_extensions.h
|
||||
* header file ensure the path to the correct header file is in the assembler's
|
||||
* include path.
|
||||
*
|
||||
* This freertos_risc_v_chip_specific_extensions.h is for use on RISC-V chips
|
||||
* that include a standard CLINT and do not add to the base set of RISC-V
|
||||
* registers.
|
||||
*
|
||||
*/
|
||||
#if __riscv_xlen == 64
|
||||
#define portWORD_SIZE 8
|
||||
#define store_x sd
|
||||
#define load_x ld
|
||||
#elif __riscv_xlen == 32
|
||||
#define store_x sw
|
||||
#define load_x lw
|
||||
#define portWORD_SIZE 4
|
||||
#else
|
||||
#define portRegNum 14
|
||||
#error Assembler did not define __riscv_xlen
|
||||
#endif
|
||||
|
||||
#define portCONTEXT_SIZE ( portRegNum * REGBYTES )
|
||||
#include "freertos_risc_v_chip_specific_extensions.h"
|
||||
|
||||
.section .text.entry
|
||||
.align 8
|
||||
/* Check the freertos_risc_v_chip_specific_extensions.h and/or command line
|
||||
definitions. */
|
||||
#ifndef portasmHAS_CLINT
|
||||
#error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_CLINT to either 1 (CLINT present) or 0 (clint not present).
|
||||
#endif
|
||||
|
||||
.extern xPortTaskSwitch
|
||||
#ifndef portasmHANDLE_INTERRUPT
|
||||
#error portasmHANDLE_INTERRUPT must be defined to the function to be called to handle external/peripheral interrupts. portasmHANDLE_INTERRUPT can be defined on the assmbler command line or in the appropriate freertos_risc_v_chip_specific_extensions.h header file.
|
||||
#endif
|
||||
|
||||
/* Only the standard core registers are stored by default. Any additional
|
||||
registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
|
||||
specific version of freertos_risc_v_chip_specific_extensions.h. See the notes
|
||||
at the top of this file. */
|
||||
#define portCONTEXT_SIZE ( 30 * portWORD_SIZE )
|
||||
|
||||
.global xPortStartFirstTask
|
||||
.global freertos_risc_v_trap_handler
|
||||
.global pxPortInitialiseStack
|
||||
.extern pxCurrentTCB
|
||||
.global prvPortStartFirstTask
|
||||
.extern ulPortTrapHandler
|
||||
.extern vTaskSwitchContext
|
||||
.extern Timer_IRQHandler
|
||||
.extern pullMachineTimerCompareRegister
|
||||
.extern pullNextTime
|
||||
.extern uxTimerIncrementsForOneTick /* size_t type so 32-bit on 32-bit core and 64-bits on 64-bit core. */
|
||||
.extern xISRStackTop
|
||||
|
||||
/**
|
||||
* \brief Global interrupt disabled
|
||||
* \details
|
||||
* This function disable global interrupt.
|
||||
* \remarks
|
||||
* - All the interrupt requests will be ignored by CPU.
|
||||
*/
|
||||
.macro DISABLE_MIE
|
||||
csrc CSR_MSTATUS, MSTATUS_MIE
|
||||
.endm
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Macro for context save
|
||||
* \details
|
||||
* This macro save ABI defined caller saved registers in the stack.
|
||||
* \remarks
|
||||
* - This Macro could use to save context when you enter to interrupt
|
||||
* or exception
|
||||
*/
|
||||
/* Save caller registers */
|
||||
.macro SAVE_CONTEXT
|
||||
csrrw sp, CSR_MSCRATCHCSWL, sp
|
||||
/* Allocate stack space for context saving */
|
||||
#ifndef __riscv_32e
|
||||
addi sp, sp, -20*REGBYTES
|
||||
#else
|
||||
addi sp, sp, -14*REGBYTES
|
||||
#endif /* __riscv_32e */
|
||||
|
||||
STORE x1, 0*REGBYTES(sp)
|
||||
STORE x4, 1*REGBYTES(sp)
|
||||
STORE x5, 2*REGBYTES(sp)
|
||||
STORE x6, 3*REGBYTES(sp)
|
||||
STORE x7, 4*REGBYTES(sp)
|
||||
STORE x10, 5*REGBYTES(sp)
|
||||
STORE x11, 6*REGBYTES(sp)
|
||||
STORE x12, 7*REGBYTES(sp)
|
||||
STORE x13, 8*REGBYTES(sp)
|
||||
STORE x14, 9*REGBYTES(sp)
|
||||
STORE x15, 10*REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
STORE x16, 14*REGBYTES(sp)
|
||||
STORE x17, 15*REGBYTES(sp)
|
||||
STORE x28, 16*REGBYTES(sp)
|
||||
STORE x29, 17*REGBYTES(sp)
|
||||
STORE x30, 18*REGBYTES(sp)
|
||||
STORE x31, 19*REGBYTES(sp)
|
||||
#endif /* __riscv_32e */
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for restore caller registers
|
||||
* \details
|
||||
* This macro restore ABI defined caller saved registers from stack.
|
||||
* \remarks
|
||||
* - You could use this macro to restore context before you want return
|
||||
* from interrupt or exeception
|
||||
*/
|
||||
/* Restore caller registers */
|
||||
.macro RESTORE_CONTEXT
|
||||
LOAD x1, 0*REGBYTES(sp)
|
||||
LOAD x4, 1*REGBYTES(sp)
|
||||
LOAD x5, 2*REGBYTES(sp)
|
||||
LOAD x6, 3*REGBYTES(sp)
|
||||
LOAD x7, 4*REGBYTES(sp)
|
||||
LOAD x10, 5*REGBYTES(sp)
|
||||
LOAD x11, 6*REGBYTES(sp)
|
||||
LOAD x12, 7*REGBYTES(sp)
|
||||
LOAD x13, 8*REGBYTES(sp)
|
||||
LOAD x14, 9*REGBYTES(sp)
|
||||
LOAD x15, 10*REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 14*REGBYTES(sp)
|
||||
LOAD x17, 15*REGBYTES(sp)
|
||||
LOAD x28, 16*REGBYTES(sp)
|
||||
LOAD x29, 17*REGBYTES(sp)
|
||||
LOAD x30, 18*REGBYTES(sp)
|
||||
LOAD x31, 19*REGBYTES(sp)
|
||||
|
||||
/* De-allocate the stack space */
|
||||
addi sp, sp, 20*REGBYTES
|
||||
#else
|
||||
/* De-allocate the stack space */
|
||||
addi sp, sp, 14*REGBYTES
|
||||
#endif /* __riscv_32e */
|
||||
csrrw sp, CSR_MSCRATCHCSWL, sp
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for save necessary CSRs to stack
|
||||
* \details
|
||||
* This macro store MCAUSE, MEPC, MSUBM to stack.
|
||||
*/
|
||||
.macro SAVE_CSR_CONTEXT
|
||||
/* Store CSR mcause to stack using pushmcause */
|
||||
csrrwi x0, CSR_PUSHMCAUSE, 11
|
||||
/* Store CSR mepc to stack using pushmepc */
|
||||
csrrwi x0, CSR_PUSHMEPC, 12
|
||||
/* Store CSR msub to stack using pushmsub */
|
||||
csrrwi x0, CSR_PUSHMSUBM, 13
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for restore necessary CSRs from stack
|
||||
* \details
|
||||
* This macro restore MSUBM, MEPC, MCAUSE from stack.
|
||||
*/
|
||||
.macro RESTORE_CSR_CONTEXT
|
||||
LOAD x5, 13*REGBYTES(sp)
|
||||
csrw CSR_MSUBM, x5
|
||||
LOAD x5, 12*REGBYTES(sp)
|
||||
csrw CSR_MEPC, x5
|
||||
LOAD x5, 11*REGBYTES(sp)
|
||||
csrw CSR_MCAUSE, x5
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Exception/NMI Entry
|
||||
* \details
|
||||
* This function provide common entry functions for exception/nmi.
|
||||
* \remarks
|
||||
* This function provide a default exception/nmi entry.
|
||||
* ABI defined caller save register and some CSR registers
|
||||
* to be saved before enter interrupt handler and be restored before return.
|
||||
*/
|
||||
.section .text.trap
|
||||
/* In CLIC mode, the exeception entry must be 64bytes aligned */
|
||||
.align 6
|
||||
.global exc_entry
|
||||
exc_entry:
|
||||
/* Save the caller saving registers (context) */
|
||||
SAVE_CONTEXT
|
||||
/* Save the necessary CSR registers */
|
||||
SAVE_CSR_CONTEXT
|
||||
|
||||
/*
|
||||
* Set the exception handler function arguments
|
||||
* argument 1: mcause value
|
||||
* argument 2: current stack point(SP) value
|
||||
*/
|
||||
csrr a0, mcause
|
||||
mv a1, sp
|
||||
/*
|
||||
* TODO: Call the exception handler function
|
||||
* By default, the function template is provided in
|
||||
* system_Device.c, you can adjust it as you want
|
||||
*/
|
||||
call core_exception_handler
|
||||
|
||||
/* Restore the necessary CSR registers */
|
||||
RESTORE_CSR_CONTEXT
|
||||
/* Restore the caller saving registers (context) */
|
||||
RESTORE_CONTEXT
|
||||
|
||||
/* Return to regular code */
|
||||
mret
|
||||
|
||||
/**
|
||||
* \brief Non-Vector Interrupt Entry
|
||||
* \details
|
||||
* This function provide common entry functions for handling
|
||||
* non-vector interrupts
|
||||
* \remarks
|
||||
* This function provide a default non-vector interrupt entry.
|
||||
* ABI defined caller save register and some CSR registers need
|
||||
* to be saved before enter interrupt handler and be restored before return.
|
||||
*/
|
||||
.section .text.irq
|
||||
/* In CLIC mode, the interrupt entry must be 4bytes aligned */
|
||||
.align 2
|
||||
.global irq_entry
|
||||
/* This label will be set to MTVT2 register */
|
||||
irq_entry:
|
||||
/* Save the caller saving registers (context) */
|
||||
SAVE_CONTEXT
|
||||
/* Save the necessary CSR registers */
|
||||
SAVE_CSR_CONTEXT
|
||||
|
||||
/* This special CSR read/write operation, which is actually
|
||||
* claim the CLIC to find its pending highest ID, if the ID
|
||||
* is not 0, then automatically enable the mstatus.MIE, and
|
||||
* jump to its vector-entry-label, and update the link register
|
||||
*/
|
||||
csrrw ra, CSR_JALMNXTI, ra
|
||||
|
||||
/* Critical section with interrupts disabled */
|
||||
DISABLE_MIE
|
||||
|
||||
/* Restore the necessary CSR registers */
|
||||
RESTORE_CSR_CONTEXT
|
||||
/* Restore the caller saving registers (context) */
|
||||
RESTORE_CONTEXT
|
||||
|
||||
/* Return to regular code */
|
||||
mret
|
||||
|
||||
/* Default Handler for Exceptions / Interrupts */
|
||||
.global default_intexc_handler
|
||||
Undef_Handler:
|
||||
default_intexc_handler:
|
||||
1:
|
||||
j 1b
|
||||
|
||||
/* Start the first task. This also clears the bit that indicates the FPU is
|
||||
in use in case the FPU was used before the scheduler was started - which
|
||||
would otherwise result in the unnecessary leaving of space in the stack
|
||||
for lazy saving of FPU registers. */
|
||||
.align 3
|
||||
prvPortStartFirstTask:
|
||||
/* Setup Interrupt Stack using
|
||||
The stack that was used by main()
|
||||
before the scheduler is started is
|
||||
no longer required after the scheduler is started.
|
||||
Interrupt stack pointer is stored in CSR_MSCRATCH */
|
||||
la t0, _sp
|
||||
csrw CSR_MSCRATCH, t0
|
||||
LOAD sp, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
LOAD sp, 0x0(sp) /* Read sp from first TCB member */
|
||||
|
||||
/* Pop PC from stack and set MEPC */
|
||||
LOAD t0, 0 * REGBYTES(sp)
|
||||
csrw CSR_MEPC, t0
|
||||
/* Pop mstatus from stack and set it */
|
||||
LOAD t0, (portRegNum - 1) * REGBYTES(sp)
|
||||
csrw CSR_MSTATUS, t0
|
||||
/* Interrupt still disable here */
|
||||
/* Restore Registers from Stack */
|
||||
LOAD x1, 1 * REGBYTES(sp) /* RA */
|
||||
LOAD x5, 2 * REGBYTES(sp)
|
||||
LOAD x6, 3 * REGBYTES(sp)
|
||||
LOAD x7, 4 * REGBYTES(sp)
|
||||
LOAD x8, 5 * REGBYTES(sp)
|
||||
LOAD x9, 6 * REGBYTES(sp)
|
||||
LOAD x10, 7 * REGBYTES(sp)
|
||||
LOAD x11, 8 * REGBYTES(sp)
|
||||
LOAD x12, 9 * REGBYTES(sp)
|
||||
LOAD x13, 10 * REGBYTES(sp)
|
||||
LOAD x14, 11 * REGBYTES(sp)
|
||||
LOAD x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 13 * REGBYTES(sp)
|
||||
LOAD x17, 14 * REGBYTES(sp)
|
||||
LOAD x18, 15 * REGBYTES(sp)
|
||||
LOAD x19, 16 * REGBYTES(sp)
|
||||
LOAD x20, 17 * REGBYTES(sp)
|
||||
LOAD x21, 18 * REGBYTES(sp)
|
||||
LOAD x22, 19 * REGBYTES(sp)
|
||||
LOAD x23, 20 * REGBYTES(sp)
|
||||
LOAD x24, 21 * REGBYTES(sp)
|
||||
LOAD x25, 22 * REGBYTES(sp)
|
||||
LOAD x26, 23 * REGBYTES(sp)
|
||||
LOAD x27, 24 * REGBYTES(sp)
|
||||
LOAD x28, 25 * REGBYTES(sp)
|
||||
LOAD x29, 26 * REGBYTES(sp)
|
||||
LOAD x30, 27 * REGBYTES(sp)
|
||||
LOAD x31, 28 * REGBYTES(sp)
|
||||
#endif
|
||||
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
|
||||
mret
|
||||
|
||||
.align 2
|
||||
.global eclic_msip_handler
|
||||
eclic_msip_handler:
|
||||
.align 8
|
||||
.func
|
||||
freertos_risc_v_trap_handler:
|
||||
addi sp, sp, -portCONTEXT_SIZE
|
||||
STORE x1, 1 * REGBYTES(sp) /* RA */
|
||||
STORE x5, 2 * REGBYTES(sp)
|
||||
STORE x6, 3 * REGBYTES(sp)
|
||||
STORE x7, 4 * REGBYTES(sp)
|
||||
STORE x8, 5 * REGBYTES(sp)
|
||||
STORE x9, 6 * REGBYTES(sp)
|
||||
STORE x10, 7 * REGBYTES(sp)
|
||||
STORE x11, 8 * REGBYTES(sp)
|
||||
STORE x12, 9 * REGBYTES(sp)
|
||||
STORE x13, 10 * REGBYTES(sp)
|
||||
STORE x14, 11 * REGBYTES(sp)
|
||||
STORE x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
STORE x16, 13 * REGBYTES(sp)
|
||||
STORE x17, 14 * REGBYTES(sp)
|
||||
STORE x18, 15 * REGBYTES(sp)
|
||||
STORE x19, 16 * REGBYTES(sp)
|
||||
STORE x20, 17 * REGBYTES(sp)
|
||||
STORE x21, 18 * REGBYTES(sp)
|
||||
STORE x22, 19 * REGBYTES(sp)
|
||||
STORE x23, 20 * REGBYTES(sp)
|
||||
STORE x24, 21 * REGBYTES(sp)
|
||||
STORE x25, 22 * REGBYTES(sp)
|
||||
STORE x26, 23 * REGBYTES(sp)
|
||||
STORE x27, 24 * REGBYTES(sp)
|
||||
STORE x28, 25 * REGBYTES(sp)
|
||||
STORE x29, 26 * REGBYTES(sp)
|
||||
STORE x30, 27 * REGBYTES(sp)
|
||||
STORE x31, 28 * REGBYTES(sp)
|
||||
#endif
|
||||
/* Push mstatus to stack */
|
||||
csrr t0, CSR_MSTATUS
|
||||
STORE t0, (portRegNum - 1) * REGBYTES(sp)
|
||||
store_x x1, 1 * portWORD_SIZE( sp )
|
||||
store_x x5, 2 * portWORD_SIZE( sp )
|
||||
store_x x6, 3 * portWORD_SIZE( sp )
|
||||
store_x x7, 4 * portWORD_SIZE( sp )
|
||||
store_x x8, 5 * portWORD_SIZE( sp )
|
||||
store_x x9, 6 * portWORD_SIZE( sp )
|
||||
store_x x10, 7 * portWORD_SIZE( sp )
|
||||
store_x x11, 8 * portWORD_SIZE( sp )
|
||||
store_x x12, 9 * portWORD_SIZE( sp )
|
||||
store_x x13, 10 * portWORD_SIZE( sp )
|
||||
store_x x14, 11 * portWORD_SIZE( sp )
|
||||
store_x x15, 12 * portWORD_SIZE( sp )
|
||||
store_x x16, 13 * portWORD_SIZE( sp )
|
||||
store_x x17, 14 * portWORD_SIZE( sp )
|
||||
store_x x18, 15 * portWORD_SIZE( sp )
|
||||
store_x x19, 16 * portWORD_SIZE( sp )
|
||||
store_x x20, 17 * portWORD_SIZE( sp )
|
||||
store_x x21, 18 * portWORD_SIZE( sp )
|
||||
store_x x22, 19 * portWORD_SIZE( sp )
|
||||
store_x x23, 20 * portWORD_SIZE( sp )
|
||||
store_x x24, 21 * portWORD_SIZE( sp )
|
||||
store_x x25, 22 * portWORD_SIZE( sp )
|
||||
store_x x26, 23 * portWORD_SIZE( sp )
|
||||
store_x x27, 24 * portWORD_SIZE( sp )
|
||||
store_x x28, 25 * portWORD_SIZE( sp )
|
||||
store_x x29, 26 * portWORD_SIZE( sp )
|
||||
store_x x30, 27 * portWORD_SIZE( sp )
|
||||
store_x x31, 28 * portWORD_SIZE( sp )
|
||||
|
||||
/* Push additional registers */
|
||||
csrr t0, mstatus /* Required for MPIE bit. */
|
||||
store_x t0, 29 * portWORD_SIZE( sp )
|
||||
|
||||
/* Store sp to task stack */
|
||||
LOAD t0, pxCurrentTCB
|
||||
STORE sp, 0(t0)
|
||||
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
||||
|
||||
csrr t0, CSR_MEPC
|
||||
STORE t0, 0(sp)
|
||||
jal xPortTaskSwitch
|
||||
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
|
||||
|
||||
/* Switch task context */
|
||||
LOAD t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
LOAD sp, 0x0(t0) /* Read sp from first TCB member */
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
|
||||
/* Pop PC from stack and set MEPC */
|
||||
LOAD t0, 0 * REGBYTES(sp)
|
||||
csrw CSR_MEPC, t0
|
||||
/* Pop additional registers */
|
||||
test_if_asynchronous:
|
||||
srli a2, a0, __riscv_xlen - 1 /* MSB of mcause is 1 if handing an asynchronous interrupt - shift to LSB to clear other bits. */
|
||||
beq a2, x0, handle_synchronous /* Branch past interrupt handing if not asynchronous. */
|
||||
store_x a1, 0( sp ) /* Asynch so save unmodified exception return address. */
|
||||
|
||||
/* Pop mstatus from stack and set it */
|
||||
LOAD t0, (portRegNum - 1) * REGBYTES(sp)
|
||||
csrw CSR_MSTATUS, t0
|
||||
/* Interrupt still disable here */
|
||||
/* Restore Registers from Stack */
|
||||
LOAD x1, 1 * REGBYTES(sp) /* RA */
|
||||
LOAD x5, 2 * REGBYTES(sp)
|
||||
LOAD x6, 3 * REGBYTES(sp)
|
||||
LOAD x7, 4 * REGBYTES(sp)
|
||||
LOAD x8, 5 * REGBYTES(sp)
|
||||
LOAD x9, 6 * REGBYTES(sp)
|
||||
LOAD x10, 7 * REGBYTES(sp)
|
||||
LOAD x11, 8 * REGBYTES(sp)
|
||||
LOAD x12, 9 * REGBYTES(sp)
|
||||
LOAD x13, 10 * REGBYTES(sp)
|
||||
LOAD x14, 11 * REGBYTES(sp)
|
||||
LOAD x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 13 * REGBYTES(sp)
|
||||
LOAD x17, 14 * REGBYTES(sp)
|
||||
LOAD x18, 15 * REGBYTES(sp)
|
||||
LOAD x19, 16 * REGBYTES(sp)
|
||||
LOAD x20, 17 * REGBYTES(sp)
|
||||
LOAD x21, 18 * REGBYTES(sp)
|
||||
LOAD x22, 19 * REGBYTES(sp)
|
||||
LOAD x23, 20 * REGBYTES(sp)
|
||||
LOAD x24, 21 * REGBYTES(sp)
|
||||
LOAD x25, 22 * REGBYTES(sp)
|
||||
LOAD x26, 23 * REGBYTES(sp)
|
||||
LOAD x27, 24 * REGBYTES(sp)
|
||||
LOAD x28, 25 * REGBYTES(sp)
|
||||
LOAD x29, 26 * REGBYTES(sp)
|
||||
LOAD x30, 27 * REGBYTES(sp)
|
||||
LOAD x31, 28 * REGBYTES(sp)
|
||||
handle_asynchronous:
|
||||
|
||||
#if( portasmHAS_CLINT != 0 )
|
||||
|
||||
test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */
|
||||
|
||||
addi t0, x0, 1
|
||||
|
||||
slli t0, t0, __riscv_xlen - 1 /* LSB is already set, shift into MSB. Shift 31 on 32-bit or 63 on 64-bit cores. */
|
||||
addi t1, t0, 7 /* 0x8000[]0007 == machine timer interrupt. */
|
||||
bne a0, t1, test_if_external_interrupt
|
||||
|
||||
load_x t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */
|
||||
load_x t1, pullNextTime /* Load the address of ullNextTime into t1. */
|
||||
|
||||
#if( __riscv_xlen == 32 )
|
||||
|
||||
/* Update the 64-bit mtimer compare match value in two 32-bit writes. */
|
||||
lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */
|
||||
lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */
|
||||
sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */
|
||||
sw t3, 4(t0) /* Store high word of ullNextTime into compare register. */
|
||||
lw t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
|
||||
add t4, t0, t2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits). */
|
||||
sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */
|
||||
add t6, t3, t5 /* Add overflow to high word of ullNextTime. */
|
||||
sw t4, 0(t1) /* Store new low word of ullNextTime. */
|
||||
sw t6, 4(t1) /* Store new high word of ullNextTime. */
|
||||
|
||||
#endif /* __riscv_xlen == 32 */
|
||||
|
||||
#if( __riscv_xlen == 64 )
|
||||
|
||||
/* Update the 64-bit mtimer compare match value. */
|
||||
ld t2, 0(t1) /* Load ullNextTime into t2. */
|
||||
sd t2, 0(t0) /* Store ullNextTime into compare register. */
|
||||
ld t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
|
||||
add t4, t0, t2 /* Add ullNextTime to the timer increments for one tick. */
|
||||
sd t4, 0(t1) /* Store ullNextTime. */
|
||||
|
||||
#endif /* __riscv_xlen == 64 */
|
||||
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal xTaskIncrementTick
|
||||
beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */
|
||||
jal vTaskSwitchContext
|
||||
j processed_source
|
||||
|
||||
test_if_external_interrupt: /* If there is a CLINT and the mtimer interrupt is not pending then check to see if an external interrupt is pending. */
|
||||
addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */
|
||||
bne a0, t1, as_yet_unhandled /* Something as yet unhandled. */
|
||||
|
||||
#endif /* portasmHAS_CLINT */
|
||||
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal portasmHANDLE_INTERRUPT /* Jump to the interrupt handler if there is no CLINT or if there is a CLINT and it has been determined that an external interrupt is pending. */
|
||||
j processed_source
|
||||
|
||||
handle_synchronous:
|
||||
addi a1, a1, 4 /* Synchronous so updated exception return address to the instruction after the instruction that generated the exeption. */
|
||||
store_x a1, 0( sp ) /* Save updated exception return address. */
|
||||
|
||||
test_if_environment_call:
|
||||
li t0, 11 /* 11 == environment call. */
|
||||
|
||||
#if( portasmMCAUSE_MASK != 0) // FIXME hkim
|
||||
li t1, portasmMCAUSE_MASK
|
||||
and a0, a0, t1
|
||||
#endif
|
||||
|
||||
bne a0, t0, is_exception /* Not an M environment call, so some other exception. */
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal vTaskSwitchContext
|
||||
j processed_source
|
||||
|
||||
is_exception:
|
||||
ebreak
|
||||
j is_exception
|
||||
|
||||
as_yet_unhandled:
|
||||
ebreak
|
||||
j as_yet_unhandled
|
||||
|
||||
processed_source:
|
||||
load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
load_x sp, 0( t1 ) /* Read sp from first TCB member. */
|
||||
|
||||
/* Load mret with the address of the next instruction in the task to run next. */
|
||||
load_x t0, 0( sp )
|
||||
csrw mepc, t0
|
||||
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
|
||||
/* Load mstatus with the interrupt enable bits used by the task. */
|
||||
load_x t0, 29 * portWORD_SIZE( sp )
|
||||
csrw mstatus, t0 /* Required for MPIE bit. */
|
||||
|
||||
load_x x1, 1 * portWORD_SIZE( sp )
|
||||
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
||||
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
||||
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
|
||||
load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */
|
||||
load_x x9, 6 * portWORD_SIZE( sp ) /* s1 */
|
||||
load_x x10, 7 * portWORD_SIZE( sp ) /* a0 */
|
||||
load_x x11, 8 * portWORD_SIZE( sp ) /* a1 */
|
||||
load_x x12, 9 * portWORD_SIZE( sp ) /* a2 */
|
||||
load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */
|
||||
load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */
|
||||
load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */
|
||||
load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */
|
||||
load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */
|
||||
load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */
|
||||
load_x x19, 16 * portWORD_SIZE( sp ) /* s3 */
|
||||
load_x x20, 17 * portWORD_SIZE( sp ) /* s4 */
|
||||
load_x x21, 18 * portWORD_SIZE( sp ) /* s5 */
|
||||
load_x x22, 19 * portWORD_SIZE( sp ) /* s6 */
|
||||
load_x x23, 20 * portWORD_SIZE( sp ) /* s7 */
|
||||
load_x x24, 21 * portWORD_SIZE( sp ) /* s8 */
|
||||
load_x x25, 22 * portWORD_SIZE( sp ) /* s9 */
|
||||
load_x x26, 23 * portWORD_SIZE( sp ) /* s10 */
|
||||
load_x x27, 24 * portWORD_SIZE( sp ) /* s11 */
|
||||
load_x x28, 25 * portWORD_SIZE( sp ) /* t3 */
|
||||
load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */
|
||||
load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */
|
||||
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
|
||||
mret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
.align 8
|
||||
.func
|
||||
xPortStartFirstTask:
|
||||
|
||||
#if( portasmHAS_CLINT != 0 )
|
||||
/* If there is a clint then interrupts can branch directly to the FreeRTOS
|
||||
trap handler. Otherwise the interrupt controller will need to be configured
|
||||
outside of this file. */
|
||||
la t0, freertos_risc_v_trap_handler
|
||||
csrw mtvec, t0
|
||||
#endif /* portasmHAS_CLILNT */
|
||||
|
||||
load_x sp, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
load_x sp, 0( sp ) /* Read sp from first TCB member. */
|
||||
|
||||
load_x x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */
|
||||
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
|
||||
load_x t0, 29 * portWORD_SIZE( sp ) /* mstatus */
|
||||
csrrw x0, mstatus, t0 /* Interrupts enabled from here! */
|
||||
|
||||
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
||||
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
||||
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
|
||||
load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */
|
||||
load_x x9, 6 * portWORD_SIZE( sp ) /* s1 */
|
||||
load_x x10, 7 * portWORD_SIZE( sp ) /* a0 */
|
||||
load_x x11, 8 * portWORD_SIZE( sp ) /* a1 */
|
||||
load_x x12, 9 * portWORD_SIZE( sp ) /* a2 */
|
||||
load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */
|
||||
load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */
|
||||
load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */
|
||||
load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */
|
||||
load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */
|
||||
load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */
|
||||
load_x x19, 16 * portWORD_SIZE( sp ) /* s3 */
|
||||
load_x x20, 17 * portWORD_SIZE( sp ) /* s4 */
|
||||
load_x x21, 18 * portWORD_SIZE( sp ) /* s5 */
|
||||
load_x x22, 19 * portWORD_SIZE( sp ) /* s6 */
|
||||
load_x x23, 20 * portWORD_SIZE( sp ) /* s7 */
|
||||
load_x x24, 21 * portWORD_SIZE( sp ) /* s8 */
|
||||
load_x x25, 22 * portWORD_SIZE( sp ) /* s9 */
|
||||
load_x x26, 23 * portWORD_SIZE( sp ) /* s10 */
|
||||
load_x x27, 24 * portWORD_SIZE( sp ) /* s11 */
|
||||
load_x x28, 25 * portWORD_SIZE( sp ) /* t3 */
|
||||
load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */
|
||||
load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */
|
||||
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
ret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Unlike other ports pxPortInitialiseStack() is written in assembly code as it
|
||||
* needs access to the portasmADDITIONAL_CONTEXT_SIZE constant. The prototype
|
||||
* for the function is as per the other ports:
|
||||
* StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters );
|
||||
*
|
||||
* As per the standard RISC-V ABI pxTopcOfStack is passed in in a0, pxCode in
|
||||
* a1, and pvParameters in a2. The new top of stack is passed out in a0.
|
||||
*
|
||||
* RISC-V maps registers to ABI names as follows (X1 to X31 integer registers
|
||||
* for the 'I' profile, X1 to X15 for the 'E' profile, currently I assumed).
|
||||
*
|
||||
* Register ABI Name Description Saver
|
||||
* x0 zero Hard-wired zero -
|
||||
* x1 ra Return address Caller
|
||||
* x2 sp Stack pointer Callee
|
||||
* x3 gp Global pointer -
|
||||
* x4 tp Thread pointer -
|
||||
* x5-7 t0-2 Temporaries Caller
|
||||
* x8 s0/fp Saved register/Frame pointer Callee
|
||||
* x9 s1 Saved register Callee
|
||||
* x10-11 a0-1 Function Arguments/return values Caller
|
||||
* x12-17 a2-7 Function arguments Caller
|
||||
* x18-27 s2-11 Saved registers Callee
|
||||
* x28-31 t3-6 Temporaries Caller
|
||||
*
|
||||
* The RISC-V context is saved t FreeRTOS tasks in the following stack frame,
|
||||
* where the global and thread pointers are currently assumed to be constant so
|
||||
* are not saved:
|
||||
*
|
||||
* mstatus
|
||||
* x31
|
||||
* x30
|
||||
* x29
|
||||
* x28
|
||||
* x27
|
||||
* x26
|
||||
* x25
|
||||
* x24
|
||||
* x23
|
||||
* x22
|
||||
* x21
|
||||
* x20
|
||||
* x19
|
||||
* x18
|
||||
* x17
|
||||
* x16
|
||||
* x15
|
||||
* x14
|
||||
* x13
|
||||
* x12
|
||||
* x11
|
||||
* pvParameters
|
||||
* x9
|
||||
* x8
|
||||
* x7
|
||||
* x6
|
||||
* x5
|
||||
* portTASK_RETURN_ADDRESS
|
||||
* [chip specific registers go here]
|
||||
* pxCode
|
||||
*/
|
||||
.align 8
|
||||
.func
|
||||
pxPortInitialiseStack:
|
||||
|
||||
csrr t0, mstatus /* Obtain current mstatus value. */
|
||||
addi t1, x0, 0x188 /* Generate the value 0x1880, which are the MPIE and MPP bits to set in mstatus. */
|
||||
slli t1, t1, 4
|
||||
or t0, t0, t1 /* Set MPIE and MPP bits in mstatus value. */
|
||||
|
||||
addi a0, a0, -portWORD_SIZE
|
||||
store_x t0, 0(a0) /* mstatus onto the stack. */
|
||||
addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x11-x31. */
|
||||
store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */
|
||||
addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9. */
|
||||
store_x x0, 0(a0) /* Return address onto the stack, could be portTASK_RETURN_ADDRESS */
|
||||
addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */
|
||||
chip_specific_stack_frame: /* First add any chip specific registers to the stack frame being created. */
|
||||
beq t0, x0, 1f /* No more chip specific registers to save. */
|
||||
addi a0, a0, -portWORD_SIZE /* Make space for chip specific register. */
|
||||
store_x x0, 0(a0) /* Give the chip specific register an initial value of zero. */
|
||||
addi t0, t0, -1 /* Decrement the count of chip specific registers remaining. */
|
||||
j chip_specific_stack_frame /* Until no more chip specific registers. */
|
||||
1:
|
||||
addi a0, a0, -portWORD_SIZE
|
||||
store_x a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */
|
||||
ret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -32,8 +32,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "nuclei_sdk_soc.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
@@ -45,61 +43,92 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#if __riscv_xlen == 64
|
||||
#define portSTACK_TYPE uint64_t
|
||||
#define portBASE_TYPE int64_t
|
||||
#define portUBASE_TYPE uint64_t
|
||||
#define portMAX_DELAY (TickType_t)0xffffffffffffffffUL
|
||||
#define portPOINTER_SIZE_TYPE uint64_t
|
||||
#elif __riscv_xlen == 32
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE int32_t
|
||||
#define portUBASE_TYPE uint32_t
|
||||
#define portMAX_DELAY (TickType_t)0xffffffffUL
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE unsigned long
|
||||
#define portBASE_TYPE long
|
||||
#define portPOINTER_SIZE_TYPE unsigned long
|
||||
|
||||
#else
|
||||
#error Assembler did not define __riscv_xlen
|
||||
#endif
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portBASE_TYPE BaseType_t;
|
||||
typedef portUBASE_TYPE UBaseType_t;
|
||||
typedef portUBASE_TYPE TickType_t;
|
||||
|
||||
#if (configUSE_16_BIT_TICKS == 1)
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY (TickType_t)0xffff
|
||||
#else
|
||||
/* RISC-V TIMER is 64-bit long */
|
||||
typedef uint64_t TickType_t;
|
||||
#define portMAX_DELAY (TickType_t)0xFFFFFFFFFFFFFFFFULL
|
||||
#endif
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH (-1)
|
||||
#define portTICK_PERIOD_MS ((TickType_t)1000 / configTICK_RATE_HZ)
|
||||
#ifdef __riscv64
|
||||
#error This is the RV32 port that has not yet been adapted for 64.
|
||||
#define portBYTE_ALIGNMENT 16
|
||||
#else
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() \
|
||||
{ \
|
||||
/* Set a software interrupt(SWI) request to request a context switch. */ \
|
||||
SysTimer_SetSWIRQ(); \
|
||||
/* Barriers are normally not required but do ensure the code is completely \
|
||||
within the specified behaviour for the architecture. */ \
|
||||
__RWMB(); \
|
||||
}
|
||||
|
||||
extern void vTaskSwitchContext(void);
|
||||
#define portYIELD() __asm volatile("ecall");
|
||||
#define portEND_SWITCHING_ISR(xSwitchRequired) \
|
||||
if (xSwitchRequired != pdFALSE) \
|
||||
portYIELD()
|
||||
if (xSwitchRequired) \
|
||||
vTaskSwitchContext()
|
||||
#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x)
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical(void);
|
||||
extern void vPortExitCritical(void);
|
||||
#define portCRITICAL_NESTING_IN_TCB 1
|
||||
extern void vTaskEnterCritical(void);
|
||||
extern void vTaskExitCritical(void);
|
||||
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
|
||||
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) (void)uxSavedStatusValue
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile("csrc mstatus, 8")
|
||||
#define portENABLE_INTERRUPTS() __asm volatile("csrs mstatus, 8")
|
||||
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
|
||||
#if (configUSE_PORT_OPTIMISED_TASK_SELECTION == 1)
|
||||
|
||||
/* Check the configuration. */
|
||||
#if (configMAX_PRIORITIES > 32)
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
|
||||
#endif
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY(uxPriority, uxReadyPriorities) (uxReadyPriorities) |= (1UL << (uxPriority))
|
||||
#define portRESET_READY_PRIORITY(uxPriority, uxReadyPriorities) (uxReadyPriorities) &= ~(1UL << (uxPriority))
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portGET_HIGHEST_PRIORITY(uxTopPriority, uxReadyPriorities) uxTopPriority = (31UL - __builtin_clz(uxReadyPriorities))
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -108,24 +137,10 @@ not necessary for to use this port. They are defined so the common demo files
|
||||
(which build with all the ports) will build. */
|
||||
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)
|
||||
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime);
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime) vPortSuppressTicksAndSleep(xExpectedIdleTime)
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#ifdef configASSERT
|
||||
extern void vPortValidateInterruptPriority(void);
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif
|
||||
|
||||
/* portNOP() is not required by this port. */
|
||||
#define portNOP() __NOP()
|
||||
#define portNOP() __asm volatile(" nop ")
|
||||
|
||||
#define portINLINE __inline
|
||||
|
||||
@@ -133,37 +148,6 @@ extern void vPortValidateInterruptPriority(void);
|
||||
#define portFORCE_INLINE inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
/* This variable should not be set in any of the FreeRTOS application
|
||||
only used internal of FreeRTOS Port code */
|
||||
extern uint8_t uxMaxSysCallMTH;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
portFORCE_INLINE static void vPortRaiseBASEPRI(void) {
|
||||
ECLIC_SetMth(uxMaxSysCallMTH);
|
||||
__RWMB();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static uint8_t ulPortRaiseBASEPRI(void) {
|
||||
uint8_t ulOriginalBASEPRI;
|
||||
|
||||
ulOriginalBASEPRI = ECLIC_GetMth();
|
||||
ECLIC_SetMth(uxMaxSysCallMTH);
|
||||
__RWMB();
|
||||
|
||||
/* This return might not be reached but is necessary to prevent compiler
|
||||
warnings. */
|
||||
return ulOriginalBASEPRI;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static void vPortSetBASEPRI(uint8_t ulNewMaskValue) {
|
||||
ECLIC_SetMth(ulNewMaskValue);
|
||||
__RWMB();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile("" ::: "memory")
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
adapter_khz 100
|
||||
reset_config srst_only
|
||||
adapter_nsrst_assert_width 100
|
||||
|
||||
interface cmsis-dap
|
||||
|
||||
transport select jtag
|
||||
adapter_khz 100
|
||||
|
||||
autoexit true
|
||||
|
||||
set _CHIPNAME riscv
|
||||
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1e200a6d
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
|
||||
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 20480 -work-area-backup 0
|
||||
|
||||
# Work-area is a space in RAM used for flash programming
|
||||
if { [info exists WORKAREASIZE] } {
|
||||
set _WORKAREASIZE $WORKAREASIZE
|
||||
} else {
|
||||
set _WORKAREASIZE 0x5000
|
||||
}
|
||||
|
||||
# Allow overriding the Flash bank size
|
||||
if { [info exists FLASH_SIZE] } {
|
||||
set _FLASH_SIZE $FLASH_SIZE
|
||||
} else {
|
||||
# autodetect size
|
||||
set _FLASH_SIZE 0
|
||||
}
|
||||
|
||||
# flash size will be probed
|
||||
set _FLASHNAME $_CHIPNAME.flash
|
||||
|
||||
flash bank $_FLASHNAME gd32vf103 0x08000000 0 0 0 $_TARGETNAME
|
||||
|
||||
# Expose Nuclei self-defined CSRS range 770-800,835-850,1984-2032,2064-2070
|
||||
# See https://github.com/riscv/riscv-gnu-toolchain/issues/319#issuecomment-358397306
|
||||
# Then user can view the csr register value in gdb using: info reg csr775 for CSR MTVT(0x307)
|
||||
riscv expose_csrs 770-800,835-850,1984-2032,2064-2070
|
||||
|
||||
riscv set_reset_timeout_sec 1
|
||||
|
||||
init
|
||||
|
||||
halt
|
||||
@@ -1,4 +0,0 @@
|
||||
#include "stub.h"
|
||||
#include <errno.h>
|
||||
|
||||
int _close(int fd) { return _stub(EBADF); }
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "stub.h"
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int _fstat(int fd, struct stat *st) { return _stub(EBADF); }
|
||||
@@ -1,13 +0,0 @@
|
||||
#include "nuclei_sdk_soc.h"
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
int _gettimeofday(struct timeval *tp, void *tzp) {
|
||||
uint64_t cycles;
|
||||
|
||||
cycles = __get_rv_cycle();
|
||||
|
||||
tp->tv_sec = cycles / SystemCoreClock;
|
||||
tp->tv_usec = (cycles % SystemCoreClock) * 1000000 / SystemCoreClock;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/* See LICENSE of license details. */
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
int _isatty(int fd) {
|
||||
if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "stub.h"
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
off_t _lseek(int fd, off_t ptr, int dir) { return _stub(EBADF); }
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "gd32vf103_usart.h"
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// #define UART_AUTO_ECHO
|
||||
|
||||
ssize_t _read(int fd, void *ptr, size_t len) { return -1; }
|
||||
@@ -1,18 +0,0 @@
|
||||
/* See LICENSE of license details. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void *_sbrk(ptrdiff_t incr) {
|
||||
extern char _end[];
|
||||
extern char _heap_end[];
|
||||
static char *curbrk = _end;
|
||||
|
||||
if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) {
|
||||
return NULL - 1;
|
||||
}
|
||||
|
||||
curbrk += incr;
|
||||
return curbrk - incr;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
static inline int _stub(int err) { return -1; }
|
||||
@@ -1,6 +1,5 @@
|
||||
#ifndef CONFIGURATION_H_
|
||||
#define CONFIGURATION_H_
|
||||
#include "Settings.h"
|
||||
#include <stdint.h>
|
||||
/**
|
||||
* Configuration.h
|
||||
|
||||
6
source/Core/CMakeLists.txt
Normal file
6
source/Core/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
add_subdirectory(brieflz)
|
||||
add_subdirectory(BSP)
|
||||
add_subdirectory(Drivers)
|
||||
add_subdirectory(LangSupport)
|
||||
add_subdirectory(Src)
|
||||
add_subdirectory(Threads)
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "BSP.h"
|
||||
#include "Buttons.hpp"
|
||||
#include "OLED.hpp"
|
||||
#include "Settings.h"
|
||||
#include "cmsis_os.h"
|
||||
#define LOGO_PAGE_LENGTH 1024
|
||||
|
||||
|
||||
25
source/Core/Drivers/CMakeLists.txt
Normal file
25
source/Core/Drivers/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(sources
|
||||
BMA223.cpp
|
||||
BootLogo.cpp
|
||||
Buttons.cpp
|
||||
I2CBB.cpp
|
||||
LIS2DH12.cpp
|
||||
MMA8652FC.cpp
|
||||
MSA301.cpp
|
||||
OLED.cpp
|
||||
SC7A20.cpp
|
||||
Si7210.cpp
|
||||
TipThermoModel.cpp
|
||||
usb-pd
|
||||
USBPD.cpp
|
||||
Utils.cpp
|
||||
)
|
||||
|
||||
|
||||
add_library(drivers ${sources})
|
||||
target_link_libraries(drivers PRIVATE BSP BSPImplementation mainSource languages PUBLIC USBPDLib FreeRTOS)
|
||||
target_include_directories(drivers PUBLIC .)
|
||||
|
||||
add_subdirectory(usb-pd)
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#ifndef FONT_H_
|
||||
#define FONT_H_
|
||||
#include "Translation.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define FONT_12_WIDTH 12
|
||||
// THE MAIN FONTS ARE NO LONGER HERE, MOVED TO PYTHON AUTO GEN
|
||||
|
||||
@@ -631,3 +631,36 @@ void OLED::drawHeatSymbol(uint8_t state) {
|
||||
}
|
||||
|
||||
bool OLED::isInitDone() { return initDone; }
|
||||
bool OLED::getRotation() {
|
||||
#ifdef OLED_FLIP
|
||||
return !inLeftHandedMode;
|
||||
#else
|
||||
return inLeftHandedMode;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OLED::setCursor(int16_t x, int16_t y) {
|
||||
cursor_x = x;
|
||||
cursor_y = y;
|
||||
}
|
||||
void OLED::refresh() {
|
||||
I2C_CLASS::Transmit(DEVICEADDR_OLED, screenBuffer, FRAMEBUFFER_START + (OLED_WIDTH * 2));
|
||||
// DMA tx time is ~ 20mS Ensure after calling this you delay for at least 25ms
|
||||
// or we need to goto double buffering
|
||||
}
|
||||
|
||||
void OLED::setDisplayState(OLED::DisplayState state) {
|
||||
displayState = state;
|
||||
screenBuffer[1] = (state == ON) ? 0xAF : 0xAE;
|
||||
}
|
||||
|
||||
// Clears the buffer
|
||||
void OLED::clearScreen() { memset(firstStripPtr, 0, OLED_WIDTH * 2); }
|
||||
// Draws the battery level symbol
|
||||
void OLED::drawBattery(uint8_t state) { drawSymbol(3 + (state > 10 ? 10 : state)); }
|
||||
// Draws a checkbox
|
||||
void OLED::drawCheckbox(bool state) { drawSymbol((state) ? 16 : 17); }
|
||||
|
||||
void OLED::drawImage(const uint8_t *buffer, uint8_t x, uint8_t width) { drawArea(x, 0, width, 16, buffer); }
|
||||
|
||||
int16_t OLED::getCursorX() { return cursor_x; }
|
||||
@@ -14,13 +14,6 @@
|
||||
#include <BSP.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "FreeRTOS.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OLED_I2CBB
|
||||
#include "I2CBB.hpp"
|
||||
@@ -48,46 +41,30 @@ public:
|
||||
static void initialize(); // Startup the I2C coms (brings screen out of reset etc)
|
||||
static bool isInitDone();
|
||||
// Draw the buffer out to the LCD using the DMA Channel
|
||||
static void refresh() {
|
||||
I2C_CLASS::Transmit(DEVICEADDR_OLED, screenBuffer, FRAMEBUFFER_START + (OLED_WIDTH * 2));
|
||||
// DMA tx time is ~ 20mS Ensure after calling this you delay for at least 25ms
|
||||
// or we need to goto double buffering
|
||||
}
|
||||
static void refresh();
|
||||
|
||||
static void setDisplayState(DisplayState state) {
|
||||
displayState = state;
|
||||
screenBuffer[1] = (state == ON) ? 0xAF : 0xAE;
|
||||
}
|
||||
static void setDisplayState(DisplayState state);
|
||||
|
||||
static void setRotation(bool leftHanded); // Set the rotation for the screen
|
||||
// Get the current rotation of the LCD
|
||||
static bool getRotation() {
|
||||
#ifdef OLED_FLIP
|
||||
return !inLeftHandedMode;
|
||||
#else
|
||||
return inLeftHandedMode;
|
||||
#endif
|
||||
}
|
||||
static bool getRotation();
|
||||
static void setBrightness(uint8_t contrast);
|
||||
static void setInverseDisplay(bool inverted);
|
||||
static int16_t getCursorX() { return cursor_x; }
|
||||
static int16_t getCursorX();
|
||||
static void print(const char *string, FontStyle fontStyle); // Draw a string to the current location, with selected font
|
||||
static void printWholeScreen(const char *string);
|
||||
// Set the cursor location by pixels
|
||||
static void setCursor(int16_t x, int16_t y) {
|
||||
cursor_x = x;
|
||||
cursor_y = y;
|
||||
}
|
||||
static void setCursor(int16_t x, int16_t y);
|
||||
// Draws an image to the buffer, at x offset from top to bottom (fixed height renders)
|
||||
static void drawImage(const uint8_t *buffer, uint8_t x, uint8_t width) { drawArea(x, 0, width, 16, buffer); }
|
||||
static void drawImage(const uint8_t *buffer, uint8_t x, uint8_t width);
|
||||
// Draws a number at the current cursor location
|
||||
static void printNumber(uint16_t number, uint8_t places, FontStyle fontStyle, bool noLeaderZeros = true);
|
||||
// Clears the buffer
|
||||
static void clearScreen() { memset(firstStripPtr, 0, OLED_WIDTH * 2); }
|
||||
static void clearScreen();
|
||||
// Draws the battery level symbol
|
||||
static void drawBattery(uint8_t state) { drawSymbol(3 + (state > 10 ? 10 : state)); }
|
||||
static void drawBattery(uint8_t state);
|
||||
// Draws a checkbox
|
||||
static void drawCheckbox(bool state) { drawSymbol((state) ? 16 : 17); }
|
||||
static void drawCheckbox(bool state);
|
||||
static void debugNumber(int32_t val, FontStyle fontStyle);
|
||||
static void drawHex(uint32_t x, FontStyle fontStyle);
|
||||
static void drawSymbol(uint8_t symbolID); // Used for drawing symbols of a predictable width
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "USBPD.h"
|
||||
#include "Settings.h"
|
||||
#include "configuration.h"
|
||||
#if POW_PD
|
||||
|
||||
|
||||
Submodule source/Core/Drivers/usb-pd updated: b38598261d...6dc1a77a8c
25
source/Core/LangSupport/CMakeLists.txt
Normal file
25
source/Core/LangSupport/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
if (LANG STREQUAL "")
|
||||
message(FATAL_ERROR "You must specify a language")
|
||||
endif()
|
||||
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "translation_${LANG}.cpp"
|
||||
COMMAND
|
||||
|
||||
python3 ${CMAKE_CURRENT_SOURCE_DIR}/../../../Translations/make_translation.py -o translation_${LANG}.cpp ${LANG}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../../Translations/translation_${LANG}.json
|
||||
VERBATIM)
|
||||
|
||||
|
||||
set(sources
|
||||
translation_${LANG}.cpp
|
||||
# lang_multi.cpp
|
||||
lang_single.cpp
|
||||
)
|
||||
|
||||
|
||||
add_library(languages ${sources})
|
||||
target_link_libraries(languages PRIVATE drivers brieflz mainSource )
|
||||
|
||||
17
source/Core/Src/CMakeLists.txt
Normal file
17
source/Core/Src/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
set(sources
|
||||
freertos.c
|
||||
FreeRTOSHooks.c
|
||||
settingsGUI.cpp
|
||||
main.cpp
|
||||
power.cpp
|
||||
QC3.cpp
|
||||
ScrollMessage.cpp
|
||||
Settings.cpp
|
||||
syscalls.c
|
||||
Translation.cpp
|
||||
)
|
||||
|
||||
|
||||
add_library(mainSource ${sources})
|
||||
target_include_directories(mainSource PUBLIC .)
|
||||
target_link_libraries(mainSource PRIVATE brieflz BSP FreeRTOS drivers languages)
|
||||
@@ -8,14 +8,8 @@
|
||||
#ifndef INC_QC3_H_
|
||||
#define INC_QC3_H_
|
||||
#include "stdint.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void seekQC(int16_t Vx10, uint16_t divisor);
|
||||
void startQC(uint16_t divisor); // Tries to negotiate QC for highest voltage, must be run after
|
||||
bool hasQCNegotiated(); // Returns true if a QC negotiation worked (we are using QC)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INC_QC3_H_ */
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "ScrollMessage.hpp"
|
||||
|
||||
#include "OLED.hpp"
|
||||
#include "Settings.h"
|
||||
#include "configuration.h"
|
||||
|
||||
/**
|
||||
|
||||
14
source/Core/Threads/CMakeLists.txt
Normal file
14
source/Core/Threads/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(sources
|
||||
GUIThread.cpp
|
||||
MOVThread.cpp
|
||||
PIDThread.cpp
|
||||
POWThread.cpp
|
||||
shared.cpp
|
||||
)
|
||||
|
||||
|
||||
add_library(threads ${sources})
|
||||
target_include_directories(threads PUBLIC .)
|
||||
target_link_libraries(threads PRIVATE mainSource drivers BSP FreeRTOS languages BSPImplementation )
|
||||
4
source/Core/Threads/shared.cpp
Normal file
4
source/Core/Threads/shared.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "main.hpp"
|
||||
#include "task.h"
|
||||
TaskHandle_t pidTaskNotification = NULL;
|
||||
10
source/Core/brieflz/CMakeLists.txt
Normal file
10
source/Core/brieflz/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set(sources
|
||||
brieflz.c
|
||||
depack.c
|
||||
)
|
||||
|
||||
|
||||
add_library(brieflz ${sources})
|
||||
target_include_directories(brieflz PUBLIC .)
|
||||
@@ -52,7 +52,7 @@ MINIWARE_INC_CMSIS_DEVICE = ./Core/BSP/Miniware/Vendor/CMSIS/Device/ST/STM32F1xx
|
||||
MINIWARE_CMSIS_CORE_INC_DIR = ./Core/BSP/Miniware/Vendor/CMSIS/Include
|
||||
MINIWARE_HAL_INC_DIR = ./Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Inc
|
||||
MINIWARE_HAL_LEGACY_INC_DIR = ./Core/BSP/Miniware/Vendor/STM32F1xx_HAL_Driver/Inc/Legacy
|
||||
MINIWARE_STARTUP_DIR = ./Startup
|
||||
MINIWARE_STARTUP_DIR = ./Core/BSP/Miniware
|
||||
MINIWARE_INC_DIR = ./Core/BSP/Miniware
|
||||
MINIWARE_LD_FILE = ./Core/BSP/Miniware/stm32f103.ld
|
||||
|
||||
@@ -60,7 +60,7 @@ MHP30_INC_CMSIS_DEVICE = ./Core/BSP/MHP30/Vendor/CMSIS/Device/ST/STM32F1xx/Inclu
|
||||
MHP30_CMSIS_CORE_INC_DIR = ./Core/BSP/MHP30/Vendor/CMSIS/Include
|
||||
MHP30_HAL_INC_DIR = ./Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc
|
||||
MHP30_HAL_LEGACY_INC_DIR = ./Core/BSP/MHP30/Vendor/STM32F1xx_HAL_Driver/Inc/Legacy
|
||||
MHP30_STARTUP_DIR = ./Startup
|
||||
MHP30_STARTUP_DIR = ./Core/BSP/MHP30
|
||||
MHP30_INC_DIR = ./Core/BSP/MHP30
|
||||
MHP30_LD_FILE = ./Core/BSP/MHP30/stm32f103.ld
|
||||
|
||||
@@ -71,8 +71,8 @@ PINE_NMSIS_INC_DIR = ./Core/BSP/Pine64/Vendor/NMSIS/Core/Include
|
||||
PINE_FREERTOS_PORT_INC_DIR = ./Core/BSP/Pine64/Vendor/OS/FreeRTOS/Source/portable/GCC
|
||||
|
||||
SOURCE_MIDDLEWARES_DIR = ./Middlewares
|
||||
FRTOS_CMIS_INC_DIR = ./Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS
|
||||
FRTOS_INC_DIR = ./Middlewares/Third_Party/FreeRTOS/Source/include
|
||||
FRTOS_CMIS_INC_DIR = ./Middlewares/FreeRTOS/Source/CMSIS_RTOS
|
||||
FRTOS_INC_DIR = ./Middlewares/FreeRTOS/Source/include
|
||||
DRIVER_INC_DIR =./Core/Drivers
|
||||
BSP_INC_DIR = ./Core/BSP
|
||||
THREADS_INC_DIR = ./Core/Threads
|
||||
|
||||
1
source/Middlewares/CMakeLists.txt
Normal file
1
source/Middlewares/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_subdirectory(FreeRTOS)
|
||||
1608
source/Middlewares/FreeRTOS/CMSIS_RTOS/cmsis_os.c
Normal file
1608
source/Middlewares/FreeRTOS/CMSIS_RTOS/cmsis_os.c
Normal file
File diff suppressed because it is too large
Load Diff
17
source/Middlewares/FreeRTOS/CMakeLists.txt
Normal file
17
source/Middlewares/FreeRTOS/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
set(sources
|
||||
croutine.c
|
||||
event_groups.c
|
||||
list.c
|
||||
queue.c
|
||||
tasks.c
|
||||
timers.c
|
||||
CMSIS_RTOS/cmsis_os.c
|
||||
)
|
||||
|
||||
|
||||
add_library(FreeRTOS ${sources})
|
||||
|
||||
#Reqired to be able to grab the freertos config header
|
||||
target_link_libraries(FreeRTOS PRIVATE BSP PUBLIC BSPImplementation)
|
||||
target_include_directories(FreeRTOS PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_RTOS)
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user