diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7902d6..3ab404f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - cpu: [atsam3x8e, atsam4s2b, lpc802, lpc1752, lpc1754, lpc1756, lpc1759, lpc1788, lpc55s66, max32625, max32660, mb9bf566k, stm32f103, stm32f407, stm32h723, tmpm373] + cpu: [atsam3x8e, atsam4s2b, lpc802, lpc1752, lpc1754, lpc1756, lpc1759, lpc1788, lpc55s66, max32625, max32660, mb9bf566k, stm32f103, stm32f407, stm32h723, tmpm373, rp2350] steps: - uses: actions/checkout@v4 diff --git a/targets/chip/rp2350/CMakeLists.txt b/targets/chip/rp2350/CMakeLists.txt new file mode 100644 index 0000000..8f59011 --- /dev/null +++ b/targets/chip/rp2350/CMakeLists.txt @@ -0,0 +1,88 @@ +# export our linkerscript +set(TARGET_LINKERSCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/linkerscript.ld" PARENT_SCOPE) + +# set the rp2350 cpu options as a seperate target so the driver layer can link agains klib +add_library(target_cpu_options INTERFACE) +set_target_properties(target_cpu_options PROPERTIES FOLDER "klib") + +# alias projectname::target_cpu_options to target_cpu_options +add_library(${PROJECT_NAME}::target_cpu_options ALIAS target_cpu_options) + +# include the arm directory for all the cmsis files +target_include_directories(target_cpu_options INTERFACE ${CMAKE_SOURCE_DIR}/targets/arm/) + +# set the cpu options for the compiler +target_compile_options(target_cpu_options INTERFACE "-mcpu=cortex-m33+nodsp") +target_compile_options(target_cpu_options INTERFACE "-mthumb") +if (DEFINED TARGET_FPU_ENABLED) + target_compile_options(target_cpu_options INTERFACE "-mfloat-abi=hard") + target_compile_options(target_cpu_options INTERFACE "-mfpu=fpv5-sp-d16") +endif() + +# set the cpu options for the linker +target_link_options(target_cpu_options INTERFACE "-mcpu=cortex-m33+nodsp") +target_link_options(target_cpu_options INTERFACE "-mthumb") +if (DEFINED TARGET_FPU_ENABLED) + target_link_options(target_cpu_options INTERFACE "-mfloat-abi=hard") + target_link_options(target_cpu_options INTERFACE "-mfpu=fpv5-sp-d16") +endif() + +# other compiler settings +target_compile_options(target_cpu_options INTERFACE "-Wno-attributes") +target_compile_options(target_cpu_options INTERFACE "-fno-non-call-exceptions") +target_compile_options(target_cpu_options INTERFACE "-fno-common") +target_compile_options(target_cpu_options INTERFACE "-ffunction-sections") +target_compile_options(target_cpu_options INTERFACE "-fdata-sections") +target_compile_options(target_cpu_options INTERFACE "-fno-exceptions") +target_compile_options(target_cpu_options INTERFACE "-fno-asynchronous-unwind-tables") + + +# cpu rp2350 target drivers +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/../../arm/vector_table/cortex-m33.cpp +) + +set(HEADERS_PRIVATE + +) + +set(HEADERS_PUBLIC + +) + +# add the target_cpu library +add_library(target_cpu OBJECT + ${SOURCES} + ${HEADERS_PUBLIC} + ${HEADERS_PRIVATE} +) +set_target_properties(target_cpu PROPERTIES FOLDER "klib") + +# alias projectname::target_cpu to target_cpu +add_library(${PROJECT_NAME}::target_cpu ALIAS target_cpu) + +# enable C++20 support for the library +target_compile_features(target_cpu PUBLIC cxx_std_20) + +# set the target_cpu for klib +get_filename_component(TARGET_CPU_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} NAME) +set(TARGET_CPU ${TARGET_CPU_FOLDER} PARENT_SCOPE) +target_compile_definitions(target_cpu PUBLIC "TARGET_CPU=${TARGET_CPU}") + +# add target specific compile options +target_compile_options(target_cpu PUBLIC $<$:-Wno-volatile>) + +# link to klib and target_cpu_options +target_link_libraries(target_cpu PUBLIC target_cpu_options) +target_link_libraries(target_cpu PUBLIC klib) + +# Global includes. Used by all targets +# Note: +# - header can be included by C++ code `#include ` +# - header location in project: ${CMAKE_CURRENT_BINARY_DIR}/generated_headers +target_include_directories( + target_cpu PUBLIC + "$" + "$" + "$" +) \ No newline at end of file diff --git a/targets/chip/rp2350/linkerscript.ld b/targets/chip/rp2350/linkerscript.ld new file mode 100644 index 0000000..b560b4c --- /dev/null +++ b/targets/chip/rp2350/linkerscript.ld @@ -0,0 +1,176 @@ +SEARCH_DIR(.); + +/* +Format configurations +*/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm"); +OUTPUT_ARCH(arm); + + +/* +The stack size used by the application. NOTE: you need to adjust according to your application. +*/ +STACK_SIZE = 0x4000; + +/* +Memories definitions +*/ +MEMORY +{ + rom (rx) : org = 0x10000000, len = 4m + ram (rwx) : org = 0x20000000, len = 520k +} + +/* +Entry point +*/ +ENTRY( __reset_handler ); + +/* +Sections +*/ +SECTIONS +{ + /* Vector table. Has the initial stack pointer and the initial + structure for the arm interrupts */ + .vectors : + { + . = ALIGN(4); + /* vector table */ + KEEP(*(.vectors .vectors.*)); + . = ALIGN(4); + } > rom + + /* Text segment, stores all user code */ + .text : + { + . = ALIGN(4); + /* text segment */ + *(.text .text.* .gnu.linkonce.t.*); + /* glue arm to thumb code, glue thumb to arm code*/ + *(.glue_7t .glue_7); + /* c++ exceptions */ + *(.eh_frame .eh_frame_hdr) + /* exception unwinding information */ + + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*); + *(.ARM.exidx*) + + . = ALIGN(4); + KEEP(*(.init)); + . = ALIGN(4); + KEEP(*(.fini)); + + . = ALIGN(4); + } > rom + + /* Read only data */ + .rodata : + { + . = ALIGN(4); + + /* Constands, strings, etc */ + *(.rodata .rodata.* .gnu.linkonce.r.*); + + . = ALIGN(4); + } > rom + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + .preinit_array : + { + . = ALIGN(4); + PROVIDE(__preinit_array_start = .); + + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(SORT(.preinit_array))) + + PROVIDE(__preinit_array_end = .); + } > rom + + .init_array : + { + . = ALIGN(4); + PROVIDE(__init_array_start = .); + + KEEP(*(SORT(.init_array.*))) + KEEP(*(SORT(.init_array))) + + PROVIDE(__init_array_end = .); + } > rom + + .fini_array : + { + . = ALIGN(4); + PROVIDE(__fini_array_start = .); + + KEEP(*(SORT(.fini_array.*))) + KEEP(*(SORT(.fini_array))) + + PROVIDE(__fini_array_end = .); + } > rom + + /* Stack segment */ + .stack (NOLOAD) : + { + . = ALIGN(4); + PROVIDE(__stack_start = .); + + . = . + STACK_SIZE; + . = ALIGN(4); + + PROVIDE(__stack_end = .); + } > ram + + /* Data that needs to be initialized to a value different than 0 */ + .data : + { + . = ALIGN(4); + PROVIDE(__data_init_start = LOADADDR(.data)); + PROVIDE(__data_start = .); + + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(.data)) + *(SORT_BY_ALIGNMENT(.data.*)) + *(SORT_BY_ALIGNMENT(.gnu.linkonce.d.*)) + . = ALIGN(4); + + PROVIDE(__data_end = .); + PROVIDE(__data_init_end = LOADADDR(.data)); + } > ram AT > rom + + /* Data that needs to be initialized to 0 */ + .bss (NOLOAD) : + { + . = ALIGN(4); + PROVIDE(__bss_start = .); + + *(SORT_BY_ALIGNMENT(.bss)) + *(SORT_BY_ALIGNMENT(.bss.*)) + *(SORT_BY_ALIGNMENT(.gnu.linkonce.b.*)) + *(COMMON); + . = ALIGN(4); + + PROVIDE(__bss_end = .); + } > ram + + /* Heap segment */ + .heap (NOLOAD) : + { + . = ALIGN(4); + PROVIDE(__heap_start = .); + PROVIDE(__heap_end = (ORIGIN(ram) + LENGTH(ram))); + } > ram + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + *(.note.GNU-stack) + } + + .ARM.attributes 0 : { KEEP(*(.ARM.attributes)) } +} diff --git a/targets/chip/rp2350/rp2350.hpp b/targets/chip/rp2350/rp2350.hpp new file mode 100644 index 0000000..6b43843 --- /dev/null +++ b/targets/chip/rp2350/rp2350.hpp @@ -0,0 +1,66 @@ +#ifndef KLIB_RP2350_HPP +#define KLIB_RP2350_HPP + +#include + +#include "rp2350.h" + +namespace klib::rp2350 { + // irq for the rp2350 + using irq0 = klib::irq::KLIB_IRQ<0, 16 + 52>; + using irq1 = klib::irq::KLIB_IRQ<1, 16 + 52>; + + /** + * @brief Get the current cpu id + * + * @return uint32_t + */ + static uint32_t get_cpu_id() { + // return the id in the cpu id register + return SIO->CPUID; + } + + /** + * @brief Enable a interrupt + * + * @tparam Irq + */ + template + static void enable_irq() { + static_assert(Irq >= static_cast(irq0::arm_vector::count), "Invalid IRQ given to enable"); + + // enable the irq + NVIC_EnableIRQ(static_cast(Irq - static_cast(irq0::arm_vector::count))); + } + + /** + * @brief Disable a interrupt + * + * @tparam Irq + */ + template + static void disable_irq() { + static_assert(Irq >= static_cast(irq0::arm_vector::count), "Invalid IRQ given to disable"); + + // disable the irq + NVIC_DisableIRQ(static_cast(Irq - static_cast(irq0::arm_vector::count))); + } + + /** + * @brief Global enable interrupts. + * + */ + static void enable_irq() { + __enable_irq(); + } + + /** + * @brief Global disable interrupts. Prevents any interrupt from triggering + * + */ + static void disable_irq() { + __disable_irq(); + } +} + +#endif