Commit df6628ca authored by bevice's avatar bevice
Browse files

Initial

parents
.settings
.project
.cproject
.idea
Debug
Release
tmp
*~
build
cmake-build-*
\ No newline at end of file
##################################################################################
# "THE ANY BEVERAGE-WARE LICENSE" (Revision 42 - based on beer-ware
# license):
# <dev@layer128.net> 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
##################################################################################
cmake_minimum_required(VERSION 2.8)
### TOOLCHAIN SETUP AREA #################################################
# Set any variables used in the toolchain prior project() call. In that
# case they are already set and used.
##########################################################################
##################################################################################
# tools to be used for programming the AVR
##################################################################################
set(AVR_UPLOADTOOL avrdude)
set(AVR_PROGRAMMER usbasp)
set(AVR_UPLOADTOOL_PORT usb)
#### For Arduino bootloader:
#set(AVR_PROGRAMMER arduino)
#set(AVR_UPLOADTOOL_PORT /dev/tty.wchusbserial1420)
#set(AVR_UPLOADTOOL_BITRATE 57600)
# AVR and fuses needs to be set
set(AVR_MCU atmega328p)
set(AVR_H_FUSE 0xDA)
set(AVR_L_FUSE 0xFF)
set(AVR_EX_FUSE 0×05)
set(MCU_SPEED "16000000UL")
### printf support
#set(EXTRA_FLAGS "-Wl,-u,vfprintf -lprintf_min")
### END TOOLCHAIN SETUP AREA #############################################
INCLUDE(generic-gcc-avr.cmake)
##########################################################################
# name your project
##########################################################################
project(twi)
##################################################################################
# add all sources and headers from ./src
##################################################################################
file(GLOB_RECURSE SRC_C_FILES ${PROJECT_SOURCE_DIR}/src/*.c)
file(GLOB_RECURSE SRC_CXX_FILES ${PROJECT_SOURCE_DIR}/src/*.cpp)
file(GLOB_RECURSE SRC_HEADERS ${PROJECT_SOURCE_DIR}/src/*.h)
##################################################################################
# add AVR executable
##################################################################################
add_avr_executable(
${PROJECT_NAME}
${SRC_C_FILES} ${SRC_CXX_FILES} ${SRC_HEADERS}
)
find_library(C_LIB c)
message(STATUS "avr-libc: ${C_LIB}")
avr_target_link_libraries(${PROJECT_NAME} ${C_LIB})
##################################################################################
# add AVR library
##################################################################################
#add_avr_library(
# <library-name>
# <sources> <headers>
#)
##################################################################################
# link library to executable
# NOTE: It needs to be the elf target.
##################################################################################
# target_link_libraries(<executable-name>-${AVR_MCU}.elf <library-name>-${AVR_MCU})
# OR easier
##########################################################################
# "THE ANY BEVERAGE-WARE LICENSE" (Revision 42 - based on beer-ware
# license):
# <dev@layer128.net> 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_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)
option(CXX_NO_THREAD_SAFE_STATICS "Don't use fread save statics in C++" ON)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;MinSizeRel" CACHE STRING "" FORCE)
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_PROCESSOR avr)
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
SET(CMAKE_CROSSCOMPILING 1)
##########################################################################
# executables in use
##########################################################################
find_program(AVR_CC avr-gcc)
find_program(AVR_CXX avr-g++)
find_program(AVR_OBJCOPY avr-objcopy)
find_program(AVR_SIZE_TOOL avr-size)
find_program(AVR_OBJDUMP avr-objdump)
##########################################################################
# 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})
##########################################################################
# 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)
if(AVR_UPLOADTOOL_BITRATE)
set(AVR_UPLOADTOOL_BITRATE_CMD "-b ${AVR_UPLOADTOOL_BITRATE}")
else(AVR_UPLOADTOOL_BITRATE)
set(AVR_UPLOADTOOL_BITRATE_CMD "")
endif(AVR_UPLOADTOOL_BITRATE)
# 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)
##########################################################################
# 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(<EXECUTABLE_NAME>-${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(bin_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.bin)
set(map_file ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}.map)
set(eeprom_image ${EXECUTABLE_NAME}${MCU_TYPE_FOR_FILENAME}-eeprom.hex)
# 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} -Wl,--gc-sections -mrelax -Wl,-Map,${map_file} ${EXTRA_FLAGS}"
)
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 ${bin_file}
COMMAND
${AVR_OBJCOPY} -j .text -j .data -O binary ${elf_file} ${bin_file}
COMMAND
${AVR_SIZE_TOOL} ${AVR_SIZE_ARGS} ${elf_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} ${eeprom_image} ${bin_file}
)
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} -p ${AVR_MCU} -c ${AVR_PROGRAMMER} ${AVR_UPLOADTOOL_OPTIONS}
-U flash:w:${hex_file}
-P ${AVR_UPLOADTOOL_PORT} ${AVR_UPLOADTOOL_BITRATE_CMD}
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_eeprom
${AVR_UPLOADTOOL} -p ${AVR_MCU} -c ${AVR_PROGRAMMER} ${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}"
)
# get status
add_custom_target(
get_status
${AVR_UPLOADTOOL} -p ${AVR_MCU} -c ${AVR_PROGRAMMER} -P ${AVR_UPLOADTOOL_PORT} -n -v
COMMENT "Get status from ${AVR_MCU}"
)
# get fuses
add_custom_target(
get_fuses
${AVR_UPLOADTOOL} -p ${AVR_MCU} -c ${AVR_PROGRAMMER} -P ${AVR_UPLOADTOOL_PORT} -n
-U lfuse:r:-:b
-U hfuse:r:-:b
COMMENT "Get fuses from ${AVR_MCU}"
)
# set fuses
add_custom_target(
set_fuses
${AVR_UPLOADTOOL} -p ${AVR_MCU} -c ${AVR_PROGRAMMER} -P ${AVR_UPLOADTOOL_PORT}
-U lfuse:w:${AVR_L_FUSE}:m
-U hfuse:w:${AVR_H_FUSE}:m
COMMENT "Setup: High Fuse: ${AVR_H_FUSE} Low Fuse: ${AVR_L_FUSE}"
)
# get oscillator calibration
add_custom_target(
get_calibration
${AVR_UPLOADTOOL} -p ${AVR_MCU} -c ${AVR_PROGRAMMER} -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} -p ${AVR_MCU} -c ${AVR_PROGRAMMER} -P ${AVR_UPLOADTOOL_PORT}
-U calibration:w:${AVR_MCU}_calib.hex
COMMENT "Program calibration status of internal oscillator from ${AVR_MCU}_calib.hex."
)
# 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
# <LIBRARY_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})
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 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)
##################################################################################
# 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}")
##################################################################################
# set build type, if not already set at cmake command line
##################################################################################
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif(NOT CMAKE_BUILD_TYPE)
##################################################################################
# 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/local/opt/avr-libc/avr/")
set(CMAKE_FIND_ROOT_PATH "/usr/local/opt/avr-libc/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")
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")
set(CMAKE_CXX_FLAGS_RELEASE "-Os")
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")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -save-temps -g -gdwarf-3 -gstrict-dwarf")
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")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -save-temps -g -gdwarf-3 -gstrict-dwarf")
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("-std=c11")
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")
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -std=c11)
if(CXX_NO_THREAD_SAFE_STATICS)
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -fno-threadsafe-statics)
endif(CXX_NO_THREAD_SAFE_STATICS)
# AVR libtwi #
/**
* \file
* \date 08.07.17
* \authors Alexander A. Kuzkin <xbevice@gmail.com>
*/
#include "libtwi.h"
#include <avr/interrupt.h>
#include "macro.h"
#include <util/delay.h>
#define TWI_START 0
#define TWI_RESTART 1
#define TWI_STOP 2
#define TWI_TRANSMIT 3
#define TWI_RECEIVE_ACK 4
#define TWI_RECEIVE_NACK 5
static volatile twi_callback_t current_callback = 0;
void twi(uint8_t action) {
switch (action) {
case TWI_START:
case TWI_RESTART:
TWCR = _BV(TWSTA) | _BV(TWEN) | _BV(TWINT) | _BV(TWIE);
break;
case TWI_STOP:
TWCR = _BV(TWSTO) | _BV(TWEN) | _BV(TWINT) | _BV(TWIE);
break;
case TWI_TRANSMIT:
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWIE);
break;
case TWI_RECEIVE_ACK:
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA) | _BV(TWIE);
break;
case TWI_RECEIVE_NACK:
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWIE);
break;
}
// if(action != TWI_STOP)while (!(TWCR & _BV(TWINT)));
// return (TWSR & 0xF8);
}
uint8_t twi_main(uint8_t action) {
switch (action) {
case TWI_START:
case TWI_RESTART:
TWCR = _BV(TWSTA) | _BV(TWEN) | _BV(TWINT);
break;
case TWI_STOP:
TWCR = _BV(TWSTO) | _BV(TWEN) | _BV(TWINT);
break;
case TWI_TRANSMIT:
TWCR = _BV(TWEN) | _BV(TWINT);
break;
case TWI_RECEIVE_ACK:
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);
break;
case TWI_RECEIVE_NACK:
TWCR = _BV(TWEN) | _BV(TWINT);
break;
}
if (action != TWI_STOP)while (!(TWCR & _BV(TWINT)));
return (TWSR & 0xF8);
}
volatile uint8_t *current_buffer;
volatile uint8_t slave_addr;