I am trying to create a generic cmake file for use with CLion and VSCode. The idea is to create one directory and within it a subdirectory per assignment (this is for my students). In the subdirectory they can create al kinds of C/C++/S sources. There is also a CMakeLists.txt that determines which additional libraries are included (and possibly compiled).
In the super or main directory there is a CMakeLists.txt as follows:
# @file CMakeLists.txt
# @brief Generic CMakeFile for ATXMega in VSCode and CLion
# @author Nico Verduin
# @date 29-3-2023
#
cmake_minimum_required(VERSION 3.12)
set(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)
project(start_voorbeelden CXX C NONE)
# add our sub projects
add_subdirectory(blink)
#add_subdirectory(blink2)
#add_subdirectory(ucg_test)
Then comes a CMakeLists.txt in the subdirectory
#
# @file CMakeLists.txt
# @brief root CMakeList.txt for sub projects
# @author Nico Verduin
# @date 29-3-2023
#
#import the standard cmake
set (USE_SPILIB 1)
#set (USE_UCGLIB 1)
include(../generic.cmake)
And last but not least the generic.cmake. This is where all te magic is supposed to happen.
#
# @file generic.cmake
# @brief Generic CMakeFile for ATXMega in VSCode and CLion
# Needs to be imported into the root of the individual
# sub projects
# @author Nico Verduin
# @date 29-3-2023
#
# give the project the root folder name
cmake_path(GET CMAKE_CURRENT_SOURCE_DIR FILENAME PROJECT_NAME)
message(STATUS "Current source dir = ${CMAKE_CURRENT_SOURCE_DIR}")
string(REPLACE " " "_" ProjectId ${PROJECT_NAME})
project(${PROJECT_NAME} C CXX NONE)
set(DEV_ROOT d:/vsavr8)
# avrdude
set(AVR_DUDE_EXECUTABLE ${DEV_ROOT}/tools/avrdude.exe)
# compiler path in root/gcc
set(COMPILE_PATH ${DEV_ROOT}/gcc/bin/)
# additional libraries
if(USE_SPILIB)
set (SPILIB "../spi/")
message (STATUS "Including ${SPILIB}")
include_directories(${SPILIB})
endif()
if(USE_UCGLIB)
set (UCGLIB "../ucglib/csrc/")
set (UCG_CALLBACK "../ucglib/callback/")
message (STATUS "Including ${UCGLIB} and ${UCG_CALLBACK}")
include_directories(${UCGLIB})
include_directories(${UCG_CALLBACK})
endif()
# CPU to build for
set(TARGET_CPU ATxmega256A3U)
# our compilers
set (CMAKE_C_COMPILER ${COMPILE_PATH}avr-gcc.exe )
set (CMAKE_CXX_COMPILER ${COMPILE_PATH}avr-g++.exe )
#check if we can find the compilers
include(../CMakeVerifyCompiler.txt)
#list all search directories
message(STATUS "Included directories")
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()
# compiler switches and definitions
# compiler switches and definitions
add_compile_definitions("__AVR_${TARGET_CPU}__")
add_compile_options("-O3")
add_compile_options(-fdata-sections)
add_compile_options(-ffunction-sections)
add_compile_options("-fpack-struct")
add_compile_options("-fshort-enums")
add_compile_options("-Wall")
add_compile_options("-Werror")
add_compile_options("-funsigned-char")
add_compile_options("-funsigned-bitfields")
add_compile_options("-c")
add_link_options(-Wl,--gc-sections)
add_link_options(-Wl,--print-memory-usage)
add_link_options(-Wl,--print-gc-sections)
# set verbose on
add_compile_options("-v")
# if you want to program in C++ or assembly that option is also added
# just the standard folders in the root
set(PROJECT_SOURCE_DIR "*.c" "*.h" "*.cpp" "*.hpp" "*.s" )
# add additional library source folders
if (USE_SPILIB)
list( APPEND PROJECT_SOURCE_DIR "${SPILIB}*.c" "${SPILIB}*.h")
endif()
if (USE_UCGLIB)
list( APPEND PROJECT_SOURCE_DIR "${UCGLIB}*.c" "${UCGLIB}*.h" "${UCG_CALLBACK}*.c" "${UCG_CALLBACK}*.h")
endif()
# get all the sources.
file(GLOB PROJECT_SRC CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR})
MESSAGE(${PROJECT_SRC})
# define our elf file
add_executable(${PROJECT_NAME}.elf
${PROJECT_SRC})
#### Uncomment this to see flashing process details
#set(FLASH_VERBOSE_FLAG "-v")
add_custom_target(FLASH_${PROJECT_NAME}
${AVR_DUDE_EXECUTABLE} -p x256a3u -P usb -c avrispmkII -b115200 ${FLASH_VERBOSE_FLAG} -U flash:w:${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf:a
DEPENDS ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf
)
Unfortunately the magic is a little disappointing. If the program it very small it compiled fine. Then I added ucg lib (from olikraus). Now the flash file is bigger than the chip's flash (atxmega256a3u). So apparantly the flash file contained all code was included (about 1.3 MBytes).
I found on the web that I should add the compiler switches
add_compile_options(-fdata-sections)
add_compile_options(-ffunction-sections)
And in the linker part
add_link_options(-Wl,--gc-sections)
Now my flashfile is reduced to 24 bytes text. I don't think that is enough.
I took a smaller test (blink with some SPI functions) and added verbose to see what is coming out. this is the output
"C:\Program Files\JetBrains\CLion 2022.2.3\bin\cmake\win\bin\cmake.exe" --build D:\vsavr8\start_voorbeeld\cmake-build-debug --target blink.elf -- -j 6
Consolidate compiler generated dependencies of target blink.elf
[ 33%] Building C object blink/CMakeFiles/blink.elf.dir/blink.c.obj
Using built-in specs.
Reading specs from d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/device-specs/specs-avr2
COLLECT_GCC=d:\vsavr8\gcc\bin\avr-gcc.exe
Target: avr
Configured with: ../configure --prefix=/opt/avr-gcc-mingw32 --target=avr --enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2 --host=x86_64-w64-mingw32 --build=x86_64-pc-linux-gnu : (reconfigured) ../configure --prefix=/opt/avr-gcc-mingw32 --target=avr --host=x86_64-w64-mingw32 --build=x86_64-pc-linux-gnu --enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2 --with-newlib --disable-__cxa_atexit --disable-threads --disable-shared --enable-static --disable-sjlj-exceptions --enable-libstdcxx --enable-lto --disable-hosted-libstdcxx
Thread model: single
gcc version 9.2.0 (GCC)
COLLECT_GCC_OPTIONS='-D' '__AVR_ATxmega256A3U__' '-I' 'D:\vsavr8\start_voorbeeld\blink\..\spi' '-g' '-O3' '-fdata-sections' '-ffunction-sections' '-fpack-struct' '-fshort-enums' '-Wall' '-Werror' '-funsigned-char' '-funsigned-bitfields' '-c' '-v' '-MD' '-MT' 'blink/CMakeFiles/blink.elf.dir/blink.c.obj' '-MF' 'CMakeFiles\blink.elf.dir\blink.c.obj.d' '-o' 'CMakeFiles\blink.elf.dir\blink.c.obj' '-c' '-specs=device-specs/specs-avr2'
d:/vsavr8/gcc/bin/../libexec/gcc/avr/9.2.0/cc1.exe -quiet -v -I D:\vsavr8\start_voorbeeld\blink\..\spi -iprefix d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/ -MD CMakeFiles\blink.elf.dir\blink.c.d -MF CMakeFiles\blink.elf.dir\blink.c.obj.d -MT blink/CMakeFiles/blink.elf.dir/blink.c.obj -D __AVR_ATxmega256A3U__ D:\vsavr8\start_voorbeeld\blink\blink.c -mn-flash=6 -mskip-bug -quiet -dumpbase blink.c -auxbase-strip CMakeFiles\blink.elf.dir\blink.c.obj -g -O3 -Wall -Werror -version -fdata-sections -ffunction-sections -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -o C:\Users\NICOVE~1\AppData\Local\Temp\ccyLTv7f.s
GNU C17 (GCC) version 9.2.0 (avr)
compiled by GNU C version 7.3-win32 20180312, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version isl-0.18-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/../../../../avr/sys-include"
ignoring duplicate directory "d:/vsavr8/gcc/lib/gcc/../../lib/gcc/avr/9.2.0/include"
ignoring duplicate directory "d:/vsavr8/gcc/lib/gcc/../../lib/gcc/avr/9.2.0/include-fixed"
ignoring nonexistent directory "d:/vsavr8/gcc/lib/gcc/../../lib/gcc/avr/9.2.0/../../../../avr/sys-include"
ignoring duplicate directory "d:/vsavr8/gcc/lib/gcc/../../lib/gcc/avr/9.2.0/../../../../avr/include"
#include "..." search starts here:
#include <...> search starts here:
D:\vsavr8\start_voorbeeld\blink\..\spi
d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/include
d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/include-fixed
d:\vsavr8\gcc\bin\../lib/gcc/avr/9.2.0/../../../../avr/include
End of search list.
GNU C17 (GCC) version 9.2.0 (avr)
compiled by GNU C version 7.3-win32 20180312, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3, isl version isl-0.18-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: cf45033fcb74fa02d7459bd3a612262e
COLLECT_GCC_OPTIONS='-D' '__AVR_ATxmega256A3U__' '-I' 'D:\vsavr8\start_voorbeeld\blink\..\spi' '-g' '-O3' '-fdata-sections' '-ffunction-sections' '-fpack-struct' '-fshort-enums' '-Wall' '-Werror' '-funsigned-char' '-funsigned-bitfields' '-c' '-v' '-MD' '-MT' 'blink/CMakeFiles/blink.elf.dir/blink.c.obj' '-MF' 'CMakeFiles\blink.elf.dir\blink.c.obj.d' '-o' 'CMakeFiles\blink.elf.dir\blink.c.obj' '-c' '-specs=device-specs/specs-avr2'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/as.exe -mmcu=avr2 -mgcc-isr -o CMakeFiles\blink.elf.dir\blink.c.obj C:\Users\NICOVE~1\AppData\Local\Temp\ccyLTv7f.s
COMPILER_PATH=d:/vsavr8/gcc/bin/../libexec/gcc/avr/9.2.0/;d:/vsavr8/gcc/bin/../libexec/gcc/;d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/
LIBRARY_PATH=d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/;d:/vsavr8/gcc/bin/../lib/gcc/;d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/lib/
COLLECT_GCC_OPTIONS='-D' '__AVR_ATxmega256A3U__' '-I' 'D:\vsavr8\start_voorbeeld\blink\..\spi' '-g' '-O3' '-fdata-sections' '-ffunction-sections' '-fpack-struct' '-fshort-enums' '-Wall' '-Werror' '-funsigned-char' '-funsigned-bitfields' '-c' '-v' '-MD' '-MT' 'blink/CMakeFiles/blink.elf.dir/blink.c.obj' '-MF' 'CMakeFiles\blink.elf.dir\blink.c.obj.d' '-o' 'CMakeFiles\blink.elf.dir\blink.c.obj' '-c' '-specs=device-specs/specs-avr2'
[ 66%] Linking C executable blink.elf
Memory region Used Size Region Size %age Used
text: 24 B 8 KB 0.29%
data: 0 GB 65440 B 0.00%
eeprom: 0 GB 64 KB 0.00%
fuse: 0 GB 1 KB 0.00%
lock: 0 GB 1 KB 0.00%
signature: 0 GB 1 KB 0.00%
user_signatures: 0 GB 1 KB 0.00%
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.spi_init' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.spi_transfer' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.spi_write' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.spi_read' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_DBLCLK_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_SPEED_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_MODE_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_MASTER_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_LSBFIRST_MASK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_SCK' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_MISO' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.rodata.__SPI_MOSI' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_info' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_abbrev' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_loc' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_aranges' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_ranges' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_line' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_str' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.comment' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_frame' in file 'CMakeFiles/blink.elf.dir/__/spi/spi.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.text.startup.main' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_info' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_abbrev' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_loc' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_aranges' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_ranges' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_line' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_str' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.comment' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
d:/vsavr8/gcc/bin/../lib/gcc/avr/9.2.0/../../../../avr/bin/ld.exe: removing unused section '.debug_frame' in file 'CMakeFiles/blink.elf.dir/blink.c.obj'
[100%] Built target blink.elf
Build finished
last but not least here is my example code:
blink.c
/**
* @file blink.c
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2023-03-29
*
* @copyright Copyright (c) 2023
*
*/
#define F_CPU 2000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <spi.h>
/**
* @brief
* @return int
*/
int main() {
spi_init();
uint8_t x = 0;;
spi_write(x);
PORTC.DIRSET = PIN0_bm; // bit 0 port C is set, it is an output
while (1) {
PORTC.OUTSET = PIN0_bm; // bit 0 port C is high, led is on
_delay_ms (500);
PORTC.OUTCLR = PIN0_bm; // bit 0 port C is low, led is off
_delay_ms (950);
}
}
spi.h and spi.c in a directory parallel to blink (called spi)
spi.h
#ifndef __SPI_H
#define __SPI_H
#include <inttypes.h>
#define SPI_SS_bm 0x10
#define SPI_MOSI_bm 0x20
#define SPI_MISO_bm 0x40
#define SPI_SCK_bm 0x80
#define FOO 0x00
// prototypes
void spi_init(void); // init spi
uint8_t spi_transfer(uint8_t data); // transfer data to slave
void spi_write(uint8_t data); // write (register?)
uint8_t spi_read(void); // read spi slave
#endif
spi.c
#include <inttypes.h>
#include <avr/io.h>
#include <spi_pins.h>
#include <spi.h>
// SPI on port D
#define __SPI_PORT PORTD
#define __SPI_DDR POR
const uint8_t __SPI_MOSI = 5;
const uint8_t __SPI_MISO = 6;
const uint8_t __SPI_SCK = 7;
const uint8_t __SPI_LSBFIRST_MASK = 0x01;
const uint8_t __SPI_MASTER_MASK = 0x01;
const uint8_t __SPI_MODE_MASK = 0x03;
const uint8_t __SPI_SPEED_MASK = 0x03;
const uint8_t __SPI_DBLCLK_MASK = 0x01;
//initialize the SPI bus
// uint8_t lsbfirst - if 0: most significant bit is transmitted first
// uint8_t master - if 1: use master mode, if 0: slave mode is used
// uint8_t mode - sets the transfer mode:
// mode leading clock edge trailing clock edge
// -----------------------------------------------
// 0 sample (rising) setup (falling)
// 1 setup (rising) sample (falling)
// 2 sample (falling) setup (rising)
// 3 setup (falling) sample (rising)
// uint8_t clkrate - spi bus clock rate, valid speeds are 0-3
// rate speed
// ------------
// 0 CPUCLK/4
// 1 CPUCLK/16
// 2 CPUCLK/64
// 3 CPUCLK/128
// uint8_t dblclk - if 1: doubles the SPI clock rate in master mode
// EXAMPLE: spi_init(0, 1, 0, 3, 0)
void spi_init(void ) {
// set IO ports
PORTD.DIRSET = 1 << TFT_SCK | 1 << TFT_MOSI | 1 << TFT_CS;
PORTD.DIRCLR = 1 << TFT_MISO;
// deselect CS
PORTD.OUTSET = 1 << TFT_CS;
SPID.CTRL = SPI_ENABLE_bm | // enable SPI
SPI_MASTER_bm | // Act as MAster
SPI_CLK2X_bm | // double clock speed
SPI_DORD_bm | // MSB first
SPI_MODE_0_gc | // SPI mode 0
SPI_PRESCALER_DIV4_gc; // prescaling 4
}
/**
* Transfer data over SPI
* @param data
* @return
*/
uint8_t spi_transfer(uint8_t data) {
SPID.DATA = data; // fill SPI data register
while (!(SPID.STATUS & (SPI_IF_bm))); // wait until transferred
return SPIC.DATA; // return sent data
}
/**
* write data but do chip select first and deselect when sent
* @param data
*/
void spi_write(uint8_t data) {
PORTD.OUTCLR = 1 << TFT_CS;
spi_transfer(data);
PORTD.OUTSET = 1 << TFT_CS;
}
uint8_t spi_read(void){
uint8_t data;
PORTD.OUTCLR = 1 << TFT_CS;
data = spi_transfer(FOO);
PORTD.OUTSET = 1 << TFT_CS;
return data;
}
The concept seems to work fine allowing students to create on directory per subject and then subdirectories per assignment. By making a generci cmake with the addational libraries they can focus on actual programming and not be disturbed by complicating stuff about the environment. And we are talking about students of who some are just learning to program for the first time of their lives.
All help will appreciated Regards Nico
Corrected files After input from @Tsyvarev the files are now as follows:
CMakeLists.txt
#
# @file CMakeLists.txt
# @brief Generic CMakeFile for ATXMega in VSCode and CLion
# @author Nico Verduin
# @date 6-4-3-2023
#
cmake_minimum_required(VERSION 3.12)
set(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)
# get our avr toolchain lo ation
include(file_locations.cmake)
# CPU to build for
set(TARGET_CPU ATxmega256A3U)
# our compilers
set (CMAKE_C_COMPILER ${COMPILE_PATH}avr-gcc.exe )
set (CMAKE_CXX_COMPILER ${COMPILE_PATH}avr-g++.exe )
set (AVR_SIZE ${COMPILE_PATH}avr-size.exe )
set (AVR_OBJCOPY ${COMPILE_PATH}avr-objcopy.exe )
#check if we can find the compilers
include(CMakeVerifyCompiler.cmake)
# ser our compiler and link options
add_compile_definitions("__AVR_${TARGET_CPU}__")
add_compile_options("-Os")
add_compile_options(-fdata-sections)
add_compile_options(-ffunction-sections)
add_compile_options("-fpack-struct")
add_compile_options("-fshort-enums")
add_compile_options("-Wall")
add_compile_options("-Werror")
add_compile_options("-funsigned-char")
add_compile_options("-funsigned-bitfields")
add_compile_options("-mmcu=${TARGET_CPU}")
add_compile_options("-c")
add_link_options(-Wl,--gc-sections)
add_link_options(-mmcu=${TARGET_CPU})
# create our root project name
get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
# this line is needed almost at the end of this CMakeLists.txt
project(start_voorbeeld CXX C NONE)
# add our sub projects
add_subdirectory(example_assignment)
add_subdirectory(blink)
add_subdirectory(ucg_test)
generic.cmake
#
# @file generic.cmake
# @brief Generic CMakeFile for ATXMega in VSCode and CLion
# Needs to be imported into the root of the individual
# sub projects
# @author Nico Verduin
# @date 6-4-2023
#
# give the project the root folder name
cmake_path(GET CMAKE_CURRENT_SOURCE_DIR FILENAME PROJECT_NAME)
string(REPLACE " " "_" ProjectId ${PROJECT_NAME})
project(${PROJECT_NAME} C CXX NONE)
# additional optional libraries
# these are switched ON in the CMakeLists.txt of a subdirectory
if(USE_SPILIB)
set (SPILIB "../spi/")
include_directories(${SPILIB})
endif()
if(USE_UCGLIB)
set (UCGLIB "../ucglib/csrc/")
set (UCG_CALLBACK "../ucglib/callback/")
include_directories(${UCGLIB})
include_directories(${UCG_CALLBACK})
endif()
add_link_options("-Wl,--Map=${PROJECT_NAME}.map")
# if you want to program in C++ or assembly that option is also added
# just the standard folders in the root
set(PROJECT_SOURCE_DIR RECURSE "*.c" "*.h" "*.cpp" "*.hpp" "*.s" )
# add additional library source folders. Keep in mind that it does not look in lower
# directories
if (USE_SPILIB)
list( APPEND PROJECT_SOURCE_DIR "${SPILIB}*.c" "${SPILIB}*.h")
endif()
if (USE_UCGLIB)
list( APPEND PROJECT_SOURCE_DIR "${UCGLIB}*.c" "${UCGLIB}*.h" "${UCG_CALLBACK}*.c" "${UCG_CALLBACK}*.h")
endif()
# get all the sources. including thous from sub directories
file(GLOB_RECURSE PROJECT_SRC CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR})
# Set to 1 in local CmakeLists.txt and will generate lots of output
if (VERBOSE)
# print the memory used in the elf file. A bit useless as it contains
# lots of info not flashed to the chip
add_link_options(-Wl,--print-memory-usage)
# outputs all the parts of .data and .text (mostly defined as .rodata)
# that are remove due to --gc-sections option
add_link_options(-Wl,--print-gc-sections)
# show in detail every compile step
add_compile_options("-v")
# set verbose on during flash
set(FLASH_VERBOSE_FLAG "-v")
endif()
# create our elf file
add_executable(${PROJECT_NAME}.elf
${PROJECT_SRC}
)
# Clean up unused and info code y removing DEBUG info etc
add_custom_command(
TARGET ${PROJECT_NAME}.elf
POST_BUILD
COMMAND ${AVR_OBJCOPY} --strip-all ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf
# and show the size of our program. Change the -A to -B to get a one line size format
# has no impact on execution
COMMAND ${AVR_SIZE} -A ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf
)
add_custom_target(${PROJECT_NAME}_FLASH
${AVR_DUDE_EXECUTABLE} -p x256a3u -P usb -c avrispmkII -b115200 ${FLASH_VERBOSE_FLAG} -U flash:w:${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf:a
DEPENDS ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf
)
Local CMakeLists.txt
#
# @file CMakeLists.txt
# @brief root CMakeList.txt for sub projects
# @author Nico Verduin
# @date 29-3-2023
#
# set optional used libraries
set (USE_SPILIB 1)
set (USE_UCGLIB 1)
# If you want to see lots of verbose output from the compilers set VERBOSE to 1
set (VERBOSE)
# do not change this line
include(../generic.cmake)