diff --git a/.gitignore b/.gitignore index 3b8da3a..a13e11f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ +.idea .pio -.vscode \ No newline at end of file +.vscode +cmake-build-* + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..989d976 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,127 @@ +cmake_minimum_required(VERSION 3.25) + +########################################################################## +# tools to beused for programming the AVR +########################################################################## +set(AVR_UPLOADTOOL avrdude) +set(AVR_PROGRAMMER avrispmkII) +set(AVR_UPLOADTOOL_PORT usb) + +########################################################################## +# AVR and fuses needs to be set +########################################################################## +set(AVR_MCU attiny85) +set(AVR_H_FUSE 0xDF) +set(AVR_L_FUSE 0xE3) +set(AVR_E_FUSE 0xFF) + +########################################################################## +# set the toolchain file +########################################################################## +set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/generic-gcc-avr.cmake) + +### END TOOLCHAIN SETUP AREA ############################################# + +########################################################################## +# define the project +########################################################################## +project(cmake-avr C CXX ASM) + +########################################################################## +# status messages +########################################################################## +message(STATUS "Current uploadtool is: ${AVR_UPLOADTOOL}") +message(STATUS "Current programmer is: ${AVR_PROGRAMMER}") +message(STATUS "Current upload port is: ${AVR_UPLOADTOOL_PORT}") +message(STATUS "Current uploadtool options are: ${AVR_UPLOADTOOL_OPTIONS}") +message(STATUS "Current MCU is set to: ${AVR_MCU}") +message(STATUS "Current H_FUSE is set to: ${AVR_H_FUSE}") +message(STATUS "Current L_FUSE is set to: ${AVR_L_FUSE}") +message(STATUS "Current E_FUSE is set to: ${AVR_E_FUSE}") + +########################################################################## +# set build type +########################################################################## +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif(NOT CMAKE_BUILD_TYPE) + +########################################################################## +# needs to be defined for AVR toolchain +########################################################################## +set(MCU_SPEED "16000000UL") + +########################################################################## +# some cmake cross-compile necessities +########################################################################## +if(DEFINED ENV{AVR_FIND_ROOT_PATH}) + set(CMAKE_FIND_ROOT_PATH $ENV{AVR_FIND_ROOT_PATH}) +else(DEFINED ENV{AVR_FIND_ROOT_PATH}) + if(EXISTS "/opt/local/avr") + set(CMAKE_FIND_ROOT_PATH "/opt/local/avr") + elseif(EXISTS "/usr/avr") + set(CMAKE_FIND_ROOT_PATH "/usr/avr") + elseif(EXISTS "/usr/lib/avr") + set(CMAKE_FIND_ROOT_PATH "/usr/lib/avr") + elseif(EXISTS "/usr/local/CrossPack-AVR") + set(CMAKE_FIND_ROOT_PATH "/usr/local/CrossPack-AVR") + else(EXISTS "/opt/local/avr") + message(FATAL_ERROR "Please set AVR_FIND_ROOT_PATH in your environment.") + endif(EXISTS "/opt/local/avr") +endif(DEFINED ENV{AVR_FIND_ROOT_PATH}) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +# not added automatically, since CMAKE_SYSTEM_NAME is "generic" +set(CMAKE_SYSTEM_INCLUDE_PATH "${CMAKE_FIND_ROOT_PATH}/include") +set(CMAKE_SYSTEM_LIBRARY_PATH "${CMAKE_FIND_ROOT_PATH}/lib") + +########################################################################## +# status messages for generating +########################################################################## +message(STATUS "Set CMAKE_FIND_ROOT_PATH to ${CMAKE_FIND_ROOT_PATH}") +message(STATUS "Set CMAKE_SYSTEM_INCLUDE_PATH to ${CMAKE_SYSTEM_INCLUDE_PATH}") +message(STATUS "Set CMAKE_SYSTEM_LIBRARY_PATH to ${CMAKE_SYSTEM_LIBRARY_PATH}") + +########################################################################## +# set compiler options for build types +########################################################################## +if(CMAKE_BUILD_TYPE MATCHES Release) + set(CMAKE_C_FLAGS_RELEASE "-Os -std=gnu99") + set(CMAKE_CXX_FLAGS_RELEASE "-Os -std=c++14") +endif(CMAKE_BUILD_TYPE MATCHES Release) + +if(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) + set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -save-temps -g -gdwarf-3 -gstrict-dwarf -std=gnu99") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -save-temps -g -gdwarf-3 -gstrict-dwarf -std=c++14") +endif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) + +if(CMAKE_BUILD_TYPE MATCHES Debug) + set(CMAKE_C_FLAGS_DEBUG "-O0 -save-temps -g -gdwarf-3 -gstrict-dwarf -std=gnu99") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -save-temps -g -gdwarf-3 -gstrict-dwarf -std=c++14") +endif(CMAKE_BUILD_TYPE MATCHES Debug) + +########################################################################## +# compiler options for all build types +########################################################################## +add_definitions("-DF_CPU=${MCU_SPEED}") +add_definitions("-fpack-struct") +add_definitions("-fshort-enums") +add_definitions("-Wall") +add_definitions("-Werror") +add_definitions("-pedantic") +add_definitions("-pedantic-errors") +add_definitions("-funsigned-char") +add_definitions("-funsigned-bitfields") +add_definitions("-ffunction-sections") +add_definitions("-c") + +########################################################################## +# include search paths +########################################################################## +include_directories(${AVR-EXAMPLE_SOURCE_DIR}/lib) + +########################################################################## +# building library and application in their subdirectories +########################################################################## +add_subdirectory(src) diff --git a/README.md b/README.md index a0e81c4..c02a5bf 100644 --- a/README.md +++ b/README.md @@ -7,23 +7,26 @@ Holder](https://sites.google.com/site/wayneholder/besting-ben-heck). The controller requires three pins on the ATtiny85. The pin assignments can be changed in the defines, but the following shows -the default layout. PB5 (Pin 1) shold probably be connected to Vcc +the default layout. PB5 (Pin 1) should probably be connected to +5V through a resistor in the 10k- to 30k-ohm range. +In this configuration, the device assumes it is the only peripheral +on the SPI bus. Accordingly, there is no provision for chip select. +This may be changed in future revisions. + ## Expected Connection Diagram +====+ - Vcc -> PB5 |* | Vcc - NC <- PB3 | | PB2 <- CLK - LEDs -- PB4 | | PB1 -- NC - GND | | PB0 <- MOSI + +5V -> PB5 |* | +5V + NC -- PB3 | | PB2 <- SCLK + DOUT <- PB4 | | PB1 -- NC + GND | | PB0 <- COPI +====+ ## Direct Dependencies -* [PlatformIO](https://platformio.org/) - -PlatformIO is used to manage the build environment. +* [GCC for AVR](https://www.microchip.com/en-us/tools-resources/develop/microchip-studio/gcc-compilers) for compiling +* [CMake](https://cmake.org/) is used to manage the build environment. ## Contribution guidelines @@ -31,4 +34,4 @@ PlatformIO is used to manage the build environment. ## For more information -* James P. Howard, II <> \ No newline at end of file +* James P. Howard, II <> diff --git a/avr-minipro.py b/avr-minipro.py deleted file mode 100644 index a79359d..0000000 --- a/avr-minipro.py +++ /dev/null @@ -1,48 +0,0 @@ -Import("env") - -upload_protocol = env.subst("$UPLOAD_PROTOCOL") - -def before_fuses(source, target, env): - print("before_fuses") - fuses_section = "fuses" - - board = env.BoardConfig() - lfuse = board.get("%s.lfuse" % fuses_section, "") - hfuse = board.get("%s.hfuse" % fuses_section, "") - efuse = board.get("%s.efuse" % fuses_section, "") - lock = board.get("%s.lock_bits" % fuses_section, "0xff") - - # write out the fuse data to a file minipro knows - fuses_file_name = env.get("BUILD_DIR") + "/" + env.get("PROGNAME") + ".fuses.conf" - env.Execute(f"echo fuses_lo = {lfuse} > {fuses_file_name}") - env.Execute(f"echo fuses_hi = {hfuse} >> {fuses_file_name}") - env.Execute(f"echo fuses_ext = {efuse} >> {fuses_file_name}") - env.Execute(f"echo lock_byte = {lock} >> {fuses_file_name}") - -if upload_protocol == "minipro": - env.AddPreAction("fuses", before_fuses) - - env.Replace( - FUSESUPLOADER="minipro", - FUSESUPLOADERFLAGS = [ - "-p", - "$BOARD_MCU", - "-c", - "config", - "-w", - "${BUILD_DIR}/${PROGNAME}.fuses.conf" - ], - SETFUSESCMD = "$FUSESUPLOADER $FUSESUPLOADERFLAGS", - ) - - env.Replace( - UPLOADER="minipro", - MINIPROFLAGS=[ - "-p", - "$BOARD", - "-f", - "ihex" - ], - UPLOADCMD="$UPLOADER $MINIPROFLAGS -w $SOURCES", - ) - upload_actions = [env.VerboseAction("$UPLOADCMD", "Uploading $SOURCE")] diff --git a/cmake/generic-gcc-avr.cmake b/cmake/generic-gcc-avr.cmake new file mode 100644 index 0000000..b9a5967 --- /dev/null +++ b/cmake/generic-gcc-avr.cmake @@ -0,0 +1,426 @@ +########################################################################## +# "THE ANY BEVERAGE-WARE LICENSE" (Revision 42 - based on beer-ware +# license): +# wrote this file. As long as you retain this notice +# you can do whatever you want with this stuff. If we meet some day, and +# you think this stuff is worth it, you can buy me a be(ve)er(age) in +# return. (I don't like beer much.) +# +# Matthias Kleemann +########################################################################## + +########################################################################## +# The toolchain requires some variables set. +# +# AVR_MCU (default: atmega8) +# the type of AVR the application is built for +# AVR_L_FUSE (NO DEFAULT) +# the LOW fuse value for the MCU used +# AVR_H_FUSE (NO DEFAULT) +# the HIGH fuse value for the MCU used +# AVR_E_FUSE (NO DEFAULT) +# the EXTENDED fuse value for the MCU used +# AVR_UPLOADTOOL (default: avrdude) +# the application used to upload to the MCU +# NOTE: The toolchain is currently quite specific about +# the commands used, so it needs tweaking. +# AVR_UPLOADTOOL_PORT (default: usb) +# the port used for the upload tool, e.g. usb +# AVR_PROGRAMMER (default: avrispmkII) +# the programmer hardware used, e.g. avrispmkII +########################################################################## + +########################################################################## +# options +########################################################################## +option(WITH_MCU "Add the mCU type to the target file name." ON) + +########################################################################## +# executables in use +########################################################################## +find_program(AVR_CC avr-gcc REQUIRED) +find_program(AVR_CXX avr-g++ REQUIRED) +find_program(AVR_OBJCOPY avr-objcopy REQUIRED) +find_program(AVR_SIZE_TOOL avr-size REQUIRED) +find_program(AVR_OBJDUMP avr-objdump REQUIRED) + +########################################################################## +# toolchain starts with defining mandatory variables +########################################################################## +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR avr) +set(CMAKE_C_COMPILER ${AVR_CC}) +set(CMAKE_CXX_COMPILER ${AVR_CXX}) + +########################################################################## +# Identification +########################################################################## +set(AVR 1) + +########################################################################## +# some necessary tools and variables for AVR builds, which may not +# defined yet +# - AVR_UPLOADTOOL +# - AVR_UPLOADTOOL_PORT +# - AVR_PROGRAMMER +# - AVR_MCU +# - AVR_SIZE_ARGS +########################################################################## + +# default upload tool +if(NOT AVR_UPLOADTOOL) + set( + AVR_UPLOADTOOL avrdude + CACHE STRING "Set default upload tool: avrdude" + ) + find_program(AVR_UPLOADTOOL avrdude) +endif(NOT AVR_UPLOADTOOL) + +# default upload tool port +if(NOT AVR_UPLOADTOOL_PORT) + set( + AVR_UPLOADTOOL_PORT usb + CACHE STRING "Set default upload tool port: usb" + ) +endif(NOT AVR_UPLOADTOOL_PORT) + +# default programmer (hardware) +if(NOT AVR_PROGRAMMER) + set( + AVR_PROGRAMMER avrispmkII + CACHE STRING "Set default programmer hardware model: avrispmkII" + ) +endif(NOT AVR_PROGRAMMER) + +# default MCU (chip) +if(NOT AVR_MCU) + set( + AVR_MCU atmega8 + CACHE STRING "Set default MCU: atmega8 (see 'avr-gcc --target-help' for valid values)" + ) +endif(NOT AVR_MCU) + +#default avr-size args +if(NOT AVR_SIZE_ARGS) + if(APPLE) + set(AVR_SIZE_ARGS -B) + else(APPLE) + set(AVR_SIZE_ARGS -C;--mcu=${AVR_MCU}) + endif(APPLE) +endif(NOT AVR_SIZE_ARGS) + +# prepare base flags for upload tool +set(AVR_UPLOADTOOL_BASE_OPTIONS -p ${AVR_MCU} -c ${AVR_PROGRAMMER}) + +# use AVR_UPLOADTOOL_BAUDRATE as baudrate for upload tool (if defined) +if(AVR_UPLOADTOOL_BAUDRATE) + set(AVR_UPLOADTOOL_BASE_OPTIONS ${AVR_UPLOADTOOL_BASE_OPTIONS} -b ${AVR_UPLOADTOOL_BAUDRATE}) +endif() + +########################################################################## +# check build types: +# - Debug +# - Release +# - RelWithDebInfo +# +# Release is chosen, because of some optimized functions in the +# AVR toolchain, e.g. _delay_ms(). +########################################################################## +if(NOT ((CMAKE_BUILD_TYPE MATCHES Release) OR +(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) OR +(CMAKE_BUILD_TYPE MATCHES Debug) OR +(CMAKE_BUILD_TYPE MATCHES MinSizeRel))) + set( + CMAKE_BUILD_TYPE Release + CACHE STRING "Choose cmake build type: Debug Release RelWithDebInfo MinSizeRel" + FORCE + ) +endif(NOT ((CMAKE_BUILD_TYPE MATCHES Release) OR +(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) OR +(CMAKE_BUILD_TYPE MATCHES Debug) OR +(CMAKE_BUILD_TYPE MATCHES MinSizeRel))) + + + +########################################################################## + +########################################################################## +# target file name add-on +########################################################################## +if(WITH_MCU) + set(MCU_TYPE_FOR_FILENAME "-${AVR_MCU}") +else(WITH_MCU) + set(MCU_TYPE_FOR_FILENAME "") +endif(WITH_MCU) + +########################################################################## +# add_avr_executable +# - IN_VAR: EXECUTABLE_NAME +# +# Creates targets and dependencies for AVR toolchain, building an +# executable. Calls add_executable with ELF file as target name, so +# any link dependencies need to be using that target, e.g. for +# target_link_libraries(-${AVR_MCU}.elf ...). +########################################################################## +function(add_avr_executable EXECUTABLE_NAME) + + if(NOT ARGN) + message(FATAL_ERROR "No source files given for ${EXECUTABLE_NAME}.") + endif(NOT ARGN) + + # set file names + set(elf_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.elf) + set(hex_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.hex) + set(lst_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.lst) + set(map_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.map) + set(eeprom_image ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}-eeprom.hex) + + set (${EXECUTABLE_NAME}_ELF_TARGET ${elf_file} PARENT_SCOPE) + set (${EXECUTABLE_NAME}_HEX_TARGET ${hex_file} PARENT_SCOPE) + set (${EXECUTABLE_NAME}_LST_TARGET ${lst_file} PARENT_SCOPE) + set (${EXECUTABLE_NAME}_MAP_TARGET ${map_file} PARENT_SCOPE) + set (${EXECUTABLE_NAME}_EEPROM_TARGET ${eeprom_file} PARENT_SCOPE) + # elf file + add_executable(${elf_file} EXCLUDE_FROM_ALL ${ARGN}) + + set_target_properties( + ${elf_file} + PROPERTIES + COMPILE_FLAGS "-mmcu=${AVR_MCU}" + LINK_FLAGS "-mmcu=${AVR_MCU} -mrelax -Wl,-Map,${map_file}" + ) + + add_custom_command( + OUTPUT ${hex_file} + COMMAND + ${AVR_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file} + COMMAND + ${AVR_SIZE_TOOL} ${AVR_SIZE_ARGS} ${elf_file} + DEPENDS ${elf_file} + ) + + add_custom_command( + OUTPUT ${lst_file} + COMMAND + ${AVR_OBJDUMP} -d ${elf_file} > ${lst_file} + DEPENDS ${elf_file} + ) + + # eeprom + add_custom_command( + OUTPUT ${eeprom_image} + COMMAND + ${AVR_OBJCOPY} -j .eeprom --set-section-flags=.eeprom=alloc,load + --change-section-lma .eeprom=0 --no-change-warnings + -O ihex ${elf_file} ${eeprom_image} + DEPENDS ${elf_file} + ) + + add_custom_target( + ${EXECUTABLE_NAME} + ALL + DEPENDS ${hex_file} ${lst_file} ${eeprom_image} + ) + + set_target_properties( + ${EXECUTABLE_NAME} + PROPERTIES + OUTPUT_NAME "${elf_file}" + ) + + # clean + get_directory_property(clean_files ADDITIONAL_MAKE_CLEAN_FILES) + set_directory_properties( + PROPERTIES + ADDITIONAL_MAKE_CLEAN_FILES "${map_file}" + ) + + # upload - with avrdude + add_custom_target( + upload_${EXECUTABLE_NAME} + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} ${AVR_UPLOADTOOL_OPTIONS} + -U flash:w:${hex_file} + -P ${AVR_UPLOADTOOL_PORT} + DEPENDS ${hex_file} + COMMENT "Uploading ${hex_file} to ${AVR_MCU} using ${AVR_PROGRAMMER}" + ) + + # upload eeprom only - with avrdude + # see also bug http://savannah.nongnu.org/bugs/?40142 + add_custom_target( + upload_${EXECUTABLE_NAME}_eeprom + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} ${AVR_UPLOADTOOL_OPTIONS} + -U eeprom:w:${eeprom_image} + -P ${AVR_UPLOADTOOL_PORT} + DEPENDS ${eeprom_image} + COMMENT "Uploading ${eeprom_image} to ${AVR_MCU} using ${AVR_PROGRAMMER}" + ) + + # disassemble + add_custom_target( + disassemble_${EXECUTABLE_NAME} + ${AVR_OBJDUMP} -h -S ${elf_file} > ${EXECUTABLE_NAME}.lst + DEPENDS ${elf_file} + ) +endfunction(add_avr_executable) + + +########################################################################## +# add_avr_library +# - IN_VAR: LIBRARY_NAME +# +# Calls add_library with an optionally concatenated name +# ${MCU_TYPE_FOR_FILENAME}. +# This needs to be used for linking against the library, e.g. calling +# target_link_libraries(...). +########################################################################## +function(add_avr_library LIBRARY_NAME) + if(NOT ARGN) + message(FATAL_ERROR "No source files given for ${LIBRARY_NAME}.") + endif(NOT ARGN) + + set(lib_file ${LIBRARY_NAME}${MCU_TYPE_FOR_FILENAME}) + set (${LIBRARY_NAME}_LIB_TARGET ${elf_file} PARENT_SCOPE) + + add_library(${lib_file} STATIC ${ARGN}) + + set_target_properties( + ${lib_file} + PROPERTIES + COMPILE_FLAGS "-mmcu=${AVR_MCU}" + OUTPUT_NAME "${lib_file}" + ) + + if(NOT TARGET ${LIBRARY_NAME}) + add_custom_target( + ${LIBRARY_NAME} + ALL + DEPENDS ${lib_file} + ) + + set_target_properties( + ${LIBRARY_NAME} + PROPERTIES + OUTPUT_NAME "${lib_file}" + ) + endif(NOT TARGET ${LIBRARY_NAME}) + +endfunction(add_avr_library) + +########################################################################## +# avr_target_link_libraries +# - IN_VAR: EXECUTABLE_TARGET +# - ARGN : targets and files to link to +# +# Calls target_link_libraries with AVR target names (concatenation, +# extensions and so on. +########################################################################## +function(avr_target_link_libraries EXECUTABLE_TARGET) + if(NOT ARGN) + message(FATAL_ERROR "Nothing to link to ${EXECUTABLE_TARGET}.") + endif(NOT ARGN) + + get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME) + + foreach(TGT ${ARGN}) + if(TARGET ${TGT}) + get_target_property(ARG_NAME ${TGT} OUTPUT_NAME) + list(APPEND NON_TARGET_LIST ${ARG_NAME}) + else(TARGET ${TGT}) + list(APPEND NON_TARGET_LIST ${TGT}) + endif(TARGET ${TGT}) + endforeach(TGT ${ARGN}) + + target_link_libraries(${TARGET_LIST} ${NON_TARGET_LIST}) +endfunction(avr_target_link_libraries EXECUTABLE_TARGET) + +########################################################################## +# avr_target_include_directories +# +# Calls target_include_directories with AVR target names +########################################################################## + +function(avr_target_include_directories EXECUTABLE_TARGET) + if(NOT ARGN) + message(FATAL_ERROR "No include directories to add to ${EXECUTABLE_TARGET}.") + endif() + + get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME) + set(extra_args ${ARGN}) + + target_include_directories(${TARGET_LIST} ${extra_args}) +endfunction() + +########################################################################## +# avr_target_compile_definitions +# +# Calls target_compile_definitions with AVR target names +########################################################################## + +function(avr_target_compile_definitions EXECUTABLE_TARGET) + if(NOT ARGN) + message(FATAL_ERROR "No compile definitions to add to ${EXECUTABLE_TARGET}.") + endif() + + get_target_property(TARGET_LIST ${EXECUTABLE_TARGET} OUTPUT_NAME) + set(extra_args ${ARGN}) + + target_compile_definitions(${TARGET_LIST} ${extra_args}) +endfunction() + +function(avr_generate_fixed_targets) + # get status + add_custom_target( + get_status + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} -n -v + COMMENT "Get status from ${AVR_MCU}" + ) + + # get fuses + add_custom_target( + get_fuses + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} -n + -U lfuse:r:-:b + -U hfuse:r:-:b + -U efuse:r:-:b + COMMENT "Get fuses from ${AVR_MCU}" + ) + + # set fuses + add_custom_target( + set_fuses + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} + -U lfuse:w:${AVR_L_FUSE}:m + -U hfuse:w:${AVR_H_FUSE}:m + -U efuse:w:${AVR_E_FUSE}:m + COMMENT "Setup: High Fuse: ${AVR_H_FUSE} Low Fuse: ${AVR_L_FUSE} Extended Fuse: ${AVR_E_FUSE}" + ) + + # get oscillator calibration + add_custom_target( + get_calibration + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} + -U calibration:r:${AVR_MCU}_calib.tmp:r + COMMENT "Write calibration status of internal oscillator to ${AVR_MCU}_calib.tmp." + ) + + # set oscillator calibration + add_custom_target( + set_calibration + ${AVR_UPLOADTOOL} ${AVR_UPLOADTOOL_BASE_OPTIONS} -P ${AVR_UPLOADTOOL_PORT} + -U calibration:w:${AVR_MCU}_calib.hex + COMMENT "Program calibration status of internal oscillator from ${AVR_MCU}_calib.hex." + ) +endfunction() + +########################################################################## +# Bypass the link step in CMake's "compiler sanity test" check +# +# CMake throws in a try_compile() target test in some generators, but does +# not know that this is a cross compiler so the executable can't link. +# Change the target type: +# +# https://stackoverflow.com/q/53633705 +########################################################################## + +set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") diff --git a/include/README b/include/README deleted file mode 100644 index 194dcd4..0000000 --- a/include/README +++ /dev/null @@ -1,39 +0,0 @@ - -This directory is intended for project header files. - -A header file is a file containing C declarations and macro definitions -to be shared between several project source files. You request the use of a -header file in your project source file (C, C++, etc) located in `src` folder -by including it, with the C preprocessing directive `#include'. - -```src/main.c - -#include "header.h" - -int main (void) -{ - ... -} -``` - -Including a header file produces the same results as copying the header file -into each source file that needs it. Such copying would be time-consuming -and error-prone. With a header file, the related declarations appear -in only one place. If they need to be changed, they can be changed in one -place, and programs that include the header file will automatically use the -new version when next recompiled. The header file eliminates the labor of -finding and changing all the copies as well as the risk that a failure to -find one copy will result in inconsistencies within a program. - -In C, the usual convention is to give header files names that end with `.h'. -It is most portable to use only letters, digits, dashes, and underscores in -header file names, and at most one dot. - -Read more about using header files in official GCC documentation: - -* Include Syntax -* Include Operation -* Once-Only Headers -* Computed Includes - -https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README deleted file mode 100644 index 6debab1..0000000 --- a/lib/README +++ /dev/null @@ -1,46 +0,0 @@ - -This directory is intended for project specific (private) libraries. -PlatformIO will compile them to static libraries and link into executable file. - -The source code of each library should be placed in a an own separate directory -("lib/your_library_name/[here are source files]"). - -For example, see a structure of the following two libraries `Foo` and `Bar`: - -|--lib -| | -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html -| | -| |--Foo -| | |- Foo.c -| | |- Foo.h -| | -| |- README --> THIS FILE -| -|- platformio.ini -|--src - |- main.c - -and a contents of `src/main.c`: -``` -#include -#include - -int main (void) -{ - ... -} - -``` - -PlatformIO Library Dependency Finder will find automatically dependent -libraries scanning project source files. - -More information about PlatformIO Library Dependency Finder -- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini deleted file mode 100644 index d66c9f9..0000000 --- a/platformio.ini +++ /dev/null @@ -1,36 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; https://docs.platformio.org/page/projectconf.html - -[platformio] -default_envs = minipro -description = WS2818B SPI Controller for ATtiny85 - -[env] -platform = atmelavr -board = attiny85 -board_build.f_cpu = 16000000L -extra_scripts = - pure-avrasm.py - avr-minipro.py -board_fuses.lfuse = 0xE2 -board_fuses.hfuse = 0xDF -board_fuses.efuse = 0xFF -build_type = release - -[env:isp] -upload_protocol = stk500v1 -upload_flags = - -P$UPLOAD_PORT - -b$UPLOAD_SPEED -upload_port = /dev/cu.usbmodem14301 -upload_speed = 19200 - -[env:minipro] -upload_protocol = minipro diff --git a/pure-avrasm.py b/pure-avrasm.py deleted file mode 100644 index e52e89c..0000000 --- a/pure-avrasm.py +++ /dev/null @@ -1,4 +0,0 @@ -Import("env") - -## Get rid of the C/C++ runtime -env.Replace(LINKFLAGS = ["-nostartfiles", "-nostdlib", "-nodefaultlibs"]) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..3fc3eca --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,15 @@ +########################################################################## +# "THE ANY BEVERAGE-WARE LICENSE" (Revision 42 - based on beer-ware +# license): +# wrote this file. As long as you retain this notice +# you can do whatever you want with this stuff. If we meet some day, and +# you think this stuff is worth it, you can buy me a be(ve)er(age) in +# return. (I don't like beer much.) +# +# Matthias Kleemann +########################################################################## + +SET(CMAKE_ASM_LINK_LIBRARY_FLAG "-nostartfiles -nostdlib -nodefaultlibs") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_ASM_LINK_LIBRARY_FLAG}") + +add_avr_executable(ws2818b-spi-controller-firmware main.S) diff --git a/src/main.S b/src/main.S index ba0f04b..60c01c3 100644 --- a/src/main.S +++ b/src/main.S @@ -26,14 +26,14 @@ ; ; The controller requires three pins on the ATtiny85. The pin ; assignments can be changed below, but the following shows the -; default layout. PB5 (Pin 1) shold probably be connected to Vcc +; default layout. PB5 (Pin 1) shold probably be connected to +5V ; through a resistor in the 10k- to 30k-ohm range. ; ; +====+ -; Vcc -> PB5 |* | Vcc +; +5V -> PB5 |* | +5V ; NC <- PB3 | | PB2 <- SCLK -; LEDs -- PB4 | | PB1 -- NC -; GND | | PB0 <- MOSI +; DOUT <- PB4 | | PB1 -- NC +; GND | | PB0 <- COPI ; +====+ #define __SFR_OFFSET 0 @@ -41,7 +41,7 @@ #include ; Give the ports we intend to use functional names -#define MOSI DDB0 +#define COPI DDB0 #define SCLK DDB2 #define DOUT DDB4 @@ -54,7 +54,7 @@ RESET: ; Reset the Attiny85 clr r17 ; Set Clock Prescaler to 1:1 (CLKPR = 0) out CLKPR, r17 - cbi DDRB, MOSI ; Set MOSI as input + cbi DDRB, COPI ; Set COPI as input cbi DDRB, SCLK ; Set SCLK as input sbi DDRB, DOUT ; Set DOUT as output cbi PORTB, DOUT ; Set DOUT LOW to clear the port @@ -66,7 +66,7 @@ WAIT_SCLK_HI: ; Wait for the next clock signal sbis PINB, SCLK ; Wait for CLK to go HIGH (rising edge) rjmp WAIT_SCLK_HI cli ; Disable interrupts for RT performance - sbis PINB, MOSI ; Skip if MOSI "1" bit + sbis PINB, COPI ; Skip if COPI "1" bit rjmp SEND_0 ; Send 0 to DOUT SEND_1: ; Else send 1 to DOUT diff --git a/test/README b/test/README deleted file mode 100644 index b94d089..0000000 --- a/test/README +++ /dev/null @@ -1,11 +0,0 @@ - -This directory is intended for PlatformIO Unit Testing and project tests. - -Unit Testing is a software testing method by which individual units of -source code, sets of one or more MCU program modules together with associated -control data, usage procedures, and operating procedures, are tested to -determine whether they are fit for use. Unit testing finds problems early -in the development cycle. - -More information about PlatformIO Unit Testing: -- https://docs.platformio.org/page/plus/unit-testing.html