diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..633a943 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +Makefile +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake +*.bin +*.elf +*.a +a.out diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7d71b65 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.5) + +include(config.cmake) +set(CMAKE_TOOLCHAIN_FILE cmake/stm32-toolchain.cmake) + +project(stm32f103c8t6 C CXX ASM) + +#Add your projects +add_subdirectory(src) + +#Add your libraries +add_subdirectory(lib) diff --git a/README.md b/README.md new file mode 100644 index 0000000..87f54e3 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +## stm32 unicore-mx cmake template + +### Introduction +This template is for developers who want to develop stm32 based firmware and use unicore-mx (https://github.com/insane-adding-machines/unicore-mx) which is a fork of libopencm3. +I have been using this template for my stm32f1 based projects. It suits my working style (make/vim). It might be useful for others. + + +### minimal setup + +#### Arch linux +- pacman -S arm-none-eabi-gcc arm-none-eabi-newlib + +#### Ubuntu +- sudo apt-get install arm-none-eabi-gcc arm-none-eabi-newlib + +#### Build + + $ git clone https://github.com/amitesh-singh/stm32-unicoremx-project + + $ cmake . + + $ make + + To upload the code to stm32f103 + $ make blink-upload + where blink is the project name. + + +#### how to use +- libraries can be added in lib/**your_new_library** and then add the entry +of your new library in *lib/CMakeLists.txt* +- projects can be added in src/**your_project_code** and then add the entry +of your new project in *src/CMakeLists.txt* +- **unicore-mx** library path can be mentioned in *config.cmake*. diff --git a/cmake/stm32-toolchain.cmake b/cmake/stm32-toolchain.cmake new file mode 100644 index 0000000..262a1df --- /dev/null +++ b/cmake/stm32-toolchain.cmake @@ -0,0 +1,95 @@ +# +# stm32 cmake toolchain for unicore-mx +# Copyright (C) 2017 Amitesh Singh +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; +# if not, see . +# +include(CMakeForceCompiler) + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR cortex-m3) + +find_program(ARM_CC arm-none-eabi-gcc + ${TOOLCHAIN_DIR}/bin) +find_program(ARM_CXX arm-none-eabi-g++ + ${TOOLCHAIN_DIR}/bin) +find_program(ARM_OBJCOPY arm-none-eabi-objcopy + ${TOOLCHAIN_DIR}/bin) +find_program(ARM_SIZE_TOOL arm-none-eabi-size + ${TOOLCHAIN_DIR}/bin) +find_program(ARM_AS arm-none-eabi-as + ${TOOLCHAIN_DIR}/bin) + +find_program(ARM_LD arm-none-eabi-ld + ${TOOLCHAIN_DIR}/bin) +find_program(ARM_OBJCOPY arm-none-eabi-objcopy + ${TOOLCHAIN_DIR}/bin) +find_program(ARM_SIZE arm-none-eabi-size + ${TOOLCHAIN_DIR}/bin) +find_program(ARM_STRIP arm-none-eabi-strip + ${TOOLCHAIN_DIR}/bin) + +find_program(ST_FLASH st-flash) +find_program(ST_INFO st-info) + +CMAKE_FORCE_C_COMPILER(${ARM_CC} GNU) +CMAKE_FORCE_CXX_COMPILER(${ARM_CXX} GNU) +set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS} "-mcpu=cortex-m3 -mthumb") + +set(BASE_PATH "${${PROJECT_NAME}_SOURCE_DIR}") +set(SRC_PATH "${BASE_PATH}/src") +set(LIB_PATH "${BASE_PATH}/lib") + +if (NOT DEFINED MCU) + set(MCU STM32F1) +endif () + +add_definitions(-D${MCU}) + +set(STM32FX_COMMONFLAGS "-Os -g -Wall -Wextra -Wshadow -mcpu=cortex-m3 -mthumb -mthumb-interwork \ + -fdata-sections -ffunction-sections -msoft-float -fno-common " CACHE STRING "") +set(STM32FX_CFLAGS " ${STM32FX_COMMONFLAGS} -fno-exceptions -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes " CACHE STRING "") +set(STM32FX_CXXFLAGS "${STM32FX_COMMONFLAGS} -fno-exceptions -Wextra -Wshadow -Wredundant-decls \ + -Weffc++" CACHE STRING "") + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${STM32FX_CFLAGS} -std=c99 " CACHE STRING "" ) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++14 ${STM32FX_CXXFLAGS} " CACHE STRING "" ) +# -lnosys --specs=rdimon.specs - removed +set(CMAKE_EXE_LINKER_FLAGS " -flto -T ${CMAKE_SOURCE_DIR}/libucmx.ld -nostartfiles -lucmx_stm32f1 -lc \ + -specs=nosys.specs -Wl,--gc-sections -Wl,--relax" CACHE STRING "") + +include_directories(${LIBUCMX_DIR}/include) +link_directories(${LIBUCMX_DIR}/lib) +link_libraries(ucmx_stm32f1) + +function(add_executable_stm32fx NAME) + add_executable(${NAME} ${ARGN}) + set_target_properties(${NAME} PROPERTIES OUTPUT_NAME "${NAME}.elf") + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${NAME}.bin") + + add_custom_command(OUTPUT ${NAME}.bin + COMMAND ${ARM_STRIP} ${NAME}.elf + COMMAND ${CMAKE_OBJCOPY} -Obinary ${NAME}.elf ${NAME}.bin + COMMAND ${ARM_SIZE} ${NAME}.elf + DEPENDS ${NAME}) + add_custom_target(${NAME}-final ALL DEPENDS ${NAME}.bin) + + add_custom_target(${NAME}-size COMMAND ${ARM_SIZE} ${NAME}.elf) + add_custom_target(${NAME}-probe COMMAND ${ST_INFO} --probe) + add_custom_target(${NAME}-upload COMMAND ${ST_FLASH} write ${NAME}.bin 0x08000000) + +endfunction(add_executable_stm32fx) diff --git a/config.cmake b/config.cmake new file mode 100644 index 0000000..1b6ccc5 --- /dev/null +++ b/config.cmake @@ -0,0 +1,26 @@ +# +# stm32 cmake toolchain for unicore-mx +# Copyright (C) 2017 Amitesh Singh +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; +# if not, see . +# + +# Always include this file before stm32-toolchain.cmake +# + +set(MCU STM32F1) + +#declare the UNICORE-MX library path +set(LIBUCMX_DIR "/home/ami/repos/unicore-mx") diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..1c371fb --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(usart1) diff --git a/lib/usart1/CMakeLists.txt b/lib/usart1/CMakeLists.txt new file mode 100644 index 0000000..f58d495 --- /dev/null +++ b/lib/usart1/CMakeLists.txt @@ -0,0 +1 @@ +add_library(usart1 usart1.h usart1.c) diff --git a/lib/usart1/usart1.c b/lib/usart1/usart1.c new file mode 100644 index 0000000..8ca26b1 --- /dev/null +++ b/lib/usart1/usart1.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +#include "usart1.h" + +void usart1_setup(void) +{ + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_USART1); + + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX); + gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, + GPIO_USART1_RX); + + usart_set_baudrate(USART1, 9600); + usart_set_databits(USART1, 8); + usart_set_stopbits(USART1, USART_STOPBITS_1); + usart_set_mode(USART1, USART_MODE_TX_RX); //USART_MODE_TX); + usart_set_parity(USART1, USART_PARITY_NONE); + usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); + + usart_enable(USART1); +} + +void usart1_print(const char *s) +{ + while (*s != 0) + { + usart_send_blocking(USART1, *s); + s++; + } +} + +void usart1_println(const char *s) +{ + usart1_print(s); + usart_send_blocking(USART1, '\r'); + usart_send_blocking(USART1, '\n'); +} diff --git a/lib/usart1/usart1.h b/lib/usart1/usart1.h new file mode 100644 index 0000000..9be8eab --- /dev/null +++ b/lib/usart1/usart1.h @@ -0,0 +1,28 @@ +/* +* usart1 +* Copyright (C) 2017 Amitesh Singh +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; +* if not, see . +* +*/ + +#ifndef _USART1_H_ +#define _USART1_H_ + +void usart1_setup(void); +void usart1_print(const char *s); +void usart1_println(const char *s); + +#endif diff --git a/libucmx.ld b/libucmx.ld new file mode 100644 index 0000000..41857d6 --- /dev/null +++ b/libucmx.ld @@ -0,0 +1,8 @@ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (xrw) : ORIGIN = 0x20000000, LENGTH = 20K +} + +INCLUDE libucmx_stm32f1.ld + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..929ee81 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(blink) +add_subdirectory(blinkcpp) diff --git a/src/blink/CMakeLists.txt b/src/blink/CMakeLists.txt new file mode 100644 index 0000000..17db51b --- /dev/null +++ b/src/blink/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable_stm32fx(blink main.c) +target_include_directories(blink PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/usart1 + ) +target_link_libraries(blink + -L${CMAKE_CURRENT_SOURCE_DIR}/../../lib/usart1 usart1 + ) diff --git a/src/blink/main.c b/src/blink/main.c new file mode 100644 index 0000000..a33ad97 --- /dev/null +++ b/src/blink/main.c @@ -0,0 +1,34 @@ +#include +#include +#include + +#include "usart1.h" + +static void my_delay_1( void ) +{ + int i = 72e6/2/4; + + while( i > 0 ) + { + i--; + __asm__( "nop" ); + } +} + +int main( void ) +{ + //set STM32 to 72 MHz + rcc_clock_setup_in_hse_8mhz_out_72mhz(); + // Enable GPIOC clock + rcc_periph_clock_enable(RCC_GPIOC); + gpio_set_mode( GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO13 ); + usart1_setup(); + + while( 1 ) + { + gpio_toggle(GPIOC, GPIO13); + my_delay_1(); + usart1_println("toggle led"); + } +} diff --git a/src/blinkcpp/CMakeLists.txt b/src/blinkcpp/CMakeLists.txt new file mode 100644 index 0000000..516f3d9 --- /dev/null +++ b/src/blinkcpp/CMakeLists.txt @@ -0,0 +1 @@ +add_executable_stm32fx(blinkcpp main.cpp) diff --git a/src/blinkcpp/main.cpp b/src/blinkcpp/main.cpp new file mode 100644 index 0000000..a288c28 --- /dev/null +++ b/src/blinkcpp/main.cpp @@ -0,0 +1,32 @@ +extern "C" { +#include +#include +#include +} + +static void my_delay_1( void ) +{ + int i = 72e6/2/4; + + while( i > 0 ) + { + i--; + __asm__( "nop" ); + } +} + +int main( void ) +{ + //set STM32 to 72 MHz + rcc_clock_setup_in_hse_8mhz_out_72mhz(); + // Enable GPIOC clock + rcc_periph_clock_enable(RCC_GPIOC); + gpio_set_mode( GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO13 ); + + while( 1 ) + { + gpio_toggle(GPIOC, GPIO13); + my_delay_1(); + } +}