Add flexible avr-mcu support

This commit is contained in:
Gregory Lirent 2023-11-19 12:25:21 +03:00
parent cad2aa91b2
commit e8d576aa49
3 changed files with 517 additions and 48 deletions

View File

@ -4,35 +4,39 @@ project(Blink VERSION 0.1.0.0 LANGUAGES C ASM)
set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD 17)
if(NOT MCU_TYPE) if(NOT M_TYPE)
set(MCU_TYPE attiny13a) set(M_TYPE attiny13a)
endif() endif()
if(NOT MCU_PROGRAMMER_SPEED) if(NOT P_CLK)
set(MCU_PROGRAMMER_SPEED 256kHz) set(P_CLK 256kHz)
endif() endif()
if(NOT MCU_PROGRAMMER) if(NOT P_TYPE)
set(MCU_PROGRAMMER usbasp) set(P_TYPE usbasp)
endif() endif()
if(NOT MCU_PROGRAMMER_PORT) if(NOT P_PORT)
set(MCU_PROGRAMMER_PORT /dev/usb/lp0) set(P_PORT /dev/usb/lp0)
endif() endif()
set(SOURCE_FILES main.c) if(NOT F_CPU)
set(F_CPU 1000000)
endif()
set(SOURCE_FILES defs.h main.c)
######################################################################################################################## ########################################################################################################################
find_program(MCU_CC avr-gcc REQUIRED) find_program(M_CC avr-gcc REQUIRED)
find_program(MCU_CXX avr-g++ REQUIRED) find_program(M_CXX avr-g++ REQUIRED)
find_program(MCU_UPLOAD_TOOL avrdude REQUIRED) find_program(M_UPLOAD_TOOL avrdude REQUIRED)
find_program(MCU_OBJCOPY avr-objcopy REQUIRED) find_program(M_OBJCOPY avr-objcopy REQUIRED)
find_program(MCU_SIZE avr-size REQUIRED) find_program(M_SIZE avr-size REQUIRED)
find_program(MCU_OBJDUMP avr-objdump REQUIRED) find_program(M_OBJDUMP avr-objdump REQUIRED)
set(CMAKE_C_COMPILER ${MCU_CC}) set(CMAKE_C_COMPILER ${M_CC})
set(CMAKE_CXX_COMPILER ${MCU_CXX}) set(CMAKE_CXX_COMPILER ${M_CXX})
if(DEFINED $ENV{AVR_ROOT_PATH}) if(DEFINED $ENV{AVR_ROOT_PATH})
set(AVR_ROOT_PATH $ENV{AVR_ROOT_PATH}) set(AVR_ROOT_PATH $ENV{AVR_ROOT_PATH})
@ -53,15 +57,24 @@ set(CMAKE_SYSTEM_LIBRARY_PATH "${AVR_ROOT_PATH}/lib")
######################################################################################################################## ########################################################################################################################
set(MCU_FLAGS -c ${MCU_PROGRAMMER} -p ${MCU_TYPE} -P ${MCU_PROGRAMMER_PORT} -B ${MCU_PROGRAMMER_SPEED}) set(M_FLAGS -c ${P_TYPE} -p ${M_TYPE} -P ${P_PORT} -B ${P_CLK})
add_definitions("-DF_CPU=${F_CPU}")
add_definitions("-fpack-struct")
add_definitions("-fshort-enums")
add_definitions("-funsigned-char")
add_definitions("-funsigned-bitfields")
add_definitions("-ffunction-sections")
add_definitions("-Wall")
add_definitions("-Werror")
if(NOT CMAKE_BUILD_TYPE OR NOT (CMAKE_BUILD_TYPE MATCHES Release OR CMAKE_BUILD_TYPE MATCHES Debug)) if(NOT CMAKE_BUILD_TYPE OR NOT (CMAKE_BUILD_TYPE MATCHES Release OR CMAKE_BUILD_TYPE MATCHES Debug))
set(CMAKE_BUILD_TYPE Debug) set(CMAKE_BUILD_TYPE Debug)
endif() endif()
if(CMAKE_BUILD_TYPE MATCHES Release) if(CMAKE_BUILD_TYPE MATCHES Release)
set(CMAKE_C_FLAGS_RELEASE "-Os") set(CMAKE_C_FLAGS_RELEASE "-Os -fno-asynchronous-unwind-tables")
set(CMAKE_CXX_FLAGS_RELEASE "-Os") set(CMAKE_CXX_FLAGS_RELEASE "-Os -fno-asynchronous-unwind-tables")
endif() endif()
if(CMAKE_BUILD_TYPE MATCHES Debug) if(CMAKE_BUILD_TYPE MATCHES Debug)
@ -76,34 +89,34 @@ function(add_mcu_executable EXECUTABLE_NAME)
message(FATAL_ERROR "No source files given for ${EXECUTABLE_NAME}") message(FATAL_ERROR "No source files given for ${EXECUTABLE_NAME}")
endif() endif()
set(elf_file ${MCU_TYPE}-${EXECUTABLE_NAME}.elf) set(elf_file ${M_TYPE}-${EXECUTABLE_NAME}.elf)
set(map_file ${MCU_TYPE}-${EXECUTABLE_NAME}.map) set(map_file ${M_TYPE}-${EXECUTABLE_NAME}.map)
set(hex_file ${MCU_TYPE}-${EXECUTABLE_NAME}.hex) set(hex_file ${M_TYPE}-${EXECUTABLE_NAME}.hex)
set(eeprom_file ${MCU_TYPE}-${EXECUTABLE_NAME}-eeprom.hex) set(eeprom_file ${M_TYPE}-${EXECUTABLE_NAME}-eeprom.hex)
add_executable(${elf_file} EXCLUDE_FROM_ALL ${ARGN}) add_executable(${elf_file} EXCLUDE_FROM_ALL ${ARGN})
set_target_properties(${elf_file} PROPERTIES set_target_properties(${elf_file} PROPERTIES
COMPILE_FLAGS "-mmcu=${MCU_TYPE}" COMPILE_FLAGS "-mmcu=${M_TYPE}"
LINK_FLAGS "-mmcu=${MCU_TYPE} -Wl,--gc-sections -mrelax -Wl,-Map,${map_file}") LINK_FLAGS "-mmcu=${M_TYPE} -Wl,--gc-sections -mrelax -Wl,-Map,${map_file}")
add_custom_command(OUTPUT ${hex_file} add_custom_command(OUTPUT ${hex_file}
COMMAND ${MCU_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file} COMMAND ${M_OBJCOPY} -j .text -j .data -O ihex ${elf_file} ${hex_file}
DEPENDS ${elf_file}) DEPENDS ${elf_file})
add_custom_command(OUTPUT ${eeprom_file} add_custom_command(OUTPUT ${eeprom_file}
COMMAND ${MCU_OBJCOPY} -j .eeprom --set-section-flags=.eeprom=alloc,load COMMAND ${M_OBJCOPY} -j .eeprom --set-section-flags=.eeprom=alloc,load
--change-section-lma .eeprom=0 --no-change-warnings --change-section-lma .eeprom=0 --no-change-warnings
-O ihex ${elf_file} ${eeprom_file} -O ihex ${elf_file} ${eeprom_file}
DEPENDS ${elf_file}) DEPENDS ${elf_file})
add_custom_target(upload_hex add_custom_target(upload_hex
${MCU_UPLOAD_TOOL} ${MCU_FLAGS} -v -U flash:w:${hex_file} ${M_UPLOAD_TOOL} ${M_FLAGS} -v -U flash:w:${hex_file}
DEPENDS ${hex_file}) DEPENDS ${hex_file})
add_custom_target(upload_eeprom add_custom_target(upload_eeprom
${MCU_UPLOAD_TOOL} ${MCU_FLAGS} -v -U eeprom:w:${eeprom_file} ${M_UPLOAD_TOOL} ${M_FLAGS} -v -U eeprom:w:${eeprom_file}
DEPENDS ${eeprom_file}) DEPENDS ${eeprom_file})
endfunction() endfunction()
add_mcu_executable(${PROJECT_NAME} main.c) add_mcu_executable(${PROJECT_NAME} ${SOURCE_FILES})

422
defs.h Normal file
View File

@ -0,0 +1,422 @@
#include <avr/io.h>
#include <util/delay.h>
#ifndef DEFS_H
#define DEFS_H
#define PORTN_MAX 0
#ifdef DDRA
# if defined(PORTA7)
# define PORTAN 8
# elif defined(PORTA6)
# define PORTAN 7
# elif defined(PORTA5)
# define PORTAN 6
# elif defined(PORTA4)
# define PORTAN 5
# elif defined(PORTA3)
# define PORTAN 4
# elif defined(PORTA2)
# define PORTAN 3
# elif defined(PORTA1)
# define PORTAN 2
# elif defined(PORTA0)
# define PORTAN 1
# else
# define PORTAN 0
# endif
#else
# define PORTAN 0
#endif
#ifdef DDRB
# if defined(PORTB7)
# define PORTBN 8
# elif defined(PORTB6)
# define PORTBN 7
# elif defined(PORTB5)
# define PORTBN 6
# elif defined(PORTB4)
# define PORTBN 5
# elif defined(PORTB3)
# define PORTBN 4
# elif defined(PORTB2)
# define PORTBN 3
# elif defined(PORTB1)
# define PORTBN 2
# elif defined(PORTB0)
# define PORTBN 1
# else
# define PORTBN 0
# endif
#else
# define PORTAN 0
#endif
#ifdef DDRC
# if defined(PORTC7)
# define PORTCN 8
# elif defined(PORTC6)
# define PORTCN 7
# elif defined(PORTC5)
# define PORTCN 6
# elif defined(PORTC4)
# define PORTCN 5
# elif defined(PORTC3)
# define PORTCN 4
# elif defined(PORTC2)
# define PORTCN 3
# elif defined(PORTC1)
# define PORTCN 2
# elif defined(PORTC0)
# define PORTCN 1
# else
# define PORTCN 0
# endif
#else
# define PORTCN 0
#endif
#ifdef DDRD
# if defined(PORTD7)
# define PORTDN 8
# elif defined(PORTD6)
# define PORTDN 7
# elif defined(PORTD5)
# define PORTDN 6
# elif defined(PORTD4)
# define PORTDN 5
# elif defined(PORTD3)
# define PORTDN 4
# elif defined(PORTD2)
# define PORTDN 3
# elif defined(PORTD1)
# define PORTDN 2
# elif defined(PORTD0)
# define PORTDN 1
# else
# define PORTDN 0
# endif
#else
# define PORTDN 0
#endif
#ifdef DDRE
# if defined(PORTE7)
# define PORTEN 8
# elif defined(PORTE6)
# define PORTEN 7
# elif defined(PORTE5)
# define PORTEN 6
# elif defined(PORTE4)
# define PORTEN 5
# elif defined(PORTE3)
# define PORTEN 4
# elif defined(PORTE2)
# define PORTEN 3
# elif defined(PORTE1)
# define PORTEN 2
# elif defined(PORTE0)
# define PORTEN 1
# else
# define PORTEN 0
# endif
#else
# define PORTEN 0
#endif
#ifdef DDRF
# if defined(PORTF7)
# define PORTFN 8
# elif defined(PORTF6)
# define PORTFN 7
# elif defined(PORTF5)
# define PORTFN 6
# elif defined(PORTF4)
# define PORTFN 5
# elif defined(PORTF3)
# define PORTFN 4
# elif defined(PORTF2)
# define PORTFN 3
# elif defined(PORTF1)
# define PORTFN 2
# elif defined(PORTF0)
# define PORTFN 1
# else
# define PORTFN 0
# endif
#else
# define PORTFN 0
#endif
#ifdef DDRG
# if defined(PORTG7)
# define PORTGN 8
# elif defined(PORTG6)
# define PORTGN 7
# elif defined(PORTG5)
# define PORTGN 6
# elif defined(PORTG4)
# define PORTGN 5
# elif defined(PORTG3)
# define PORTGN 4
# elif defined(PORTG2)
# define PORTGN 3
# elif defined(PORTG1)
# define PORTGN 2
# elif defined(PORTG0)
# define PORTGN 1
# else
# define PORTGN 0
# endif
#else
# define PORTGN 0
#endif
#ifdef DDRH
# if defined(PORTH7)
# define PORTHN 8
# elif defined(PORTH6)
# define PORTHN 7
# elif defined(PORTH5)
# define PORTHN 6
# elif defined(PORTH4)
# define PORTHN 5
# elif defined(PORTH3)
# define PORTHN 4
# elif defined(PORTH2)
# define PORTHN 3
# elif defined(PORTH1)
# define PORTHN 2
# elif defined(PORTH0)
# define PORTHN 1
# else
# define PORTHN 0
# endif
#else
# define PORTHN 0
#endif
#if defined (__AVR_AT90PWM1__) || defined (__AVR_AT90PWM2__) || defined (__AVR_AT90PWM2B__) || \
defined (__AVR_AT90PWM3__) || defined (__AVR_AT90PWM3B__) || defined (__AVR_AT90PWM216__) || \
defined (__AVR_AT90PWM316__) || defined (__AVR_AT90PWM161__) || defined (__AVR_AT90PWM81__)
#undef PORTE_EXC
#elif defined (__AVR_ATtiny26__) || defined (__AVR_ATtiny261__) || defined (__AVR_ATtiny261A__) || \
defined (__AVR_ATtiny461__) || defined (__AVR_ATtiny461A__) || defined (__AVR_ATtiny861__) || \
defined (__AVR_ATtiny861A__) || defined (__AVR_ATtiny87__) || defined (__AVR_ATtiny167__) || \
defined (__AVR_ATA5505__)
#undef PORTB_EXC
#define PORTB_EXC 7
#elif defined (__AVR_ATtiny4__) || defined (__AVR_ATtiny5__) || defined (__AVR_ATtiny9__) || \
defined (__AVR_ATtiny10__) || defined (__AVR_ATtiny20__) || defined (__AVR_ATtiny441__) || \
defined (__AVR_ATtiny841__) || defined (__AVR_ATtiny24__) || defined (__AVR_ATtiny24A__) || \
defined (__AVR_ATtiny44__) || defined (__AVR_ATtiny44A__) || defined (__AVR_ATtiny84__)
#undef PORTB_EXC
#define PORTB_EXC 3
#elif defined (__AVR_ATtiny40__) || defined (__AVR_ATtiny1634__)
#undef PORTC_EXC
#define PORTC_EXC 3
#elif defined (__AVR_ATtiny43U__)
#undef PORTA_EXC
#define PORTA_EXC 7
#elif defined (__AVR_ATtiny828__)
#undef PORTD_EXC
#define PORTD_EXC 2
#elif defined (__AVR_ATA5782__) || defined (__AVR_ATA5831__)
#undef PORTC_EXC
#define PORTC_EXC 0
#elif defined (__AVR_ATmega16M1__) || defined (__AVR_ATmega32M1__) || defined (__AVR_ATmega64M1__) || \
defined (__AVR_ATmega32C1__) || defined (__AVR_ATmega64C1__)
#undef PORTE_EXC
#define PORTE_EXC 0
#elif defined (__AVR_AT90USB82__) || defined (__AVR_AT90USB162__) || defined (__AVR_ATmega8U2__) || \
defined (__AVR_ATmega16U2__) || defined (__AVR_ATmega32U2__)
#undef PORTC_EXC
#define PORTC_EXC 1
#elif defined (__AVR_ATmega8HVA__) || defined (__AVR_ATmega16HVA__) || defined (__AVR_ATmega16HVA2__) || \
defined (__AVR_ATtiny2313__) || defined (__AVR_ATtiny2313A__) || defined (__AVR_ATtiny4313__)
#undef PORTA_EXC
#define PORTA_EXC 2
#elif defined (__AVR_ATmega165__) || defined (__AVR_ATmega165A__) || defined (__AVR_ATmega165P__) || \
defined (__AVR_ATmega325__) || defined (__AVR_ATmega325A__) || defined (__AVR_ATmega325P__) || \
defined (__AVR_ATmega325PA__) || defined (__AVR_ATmega3250__) || defined (__AVR_ATmega3250A__) || \
defined (__AVR_ATmega3250P__) || defined (__AVR_ATmega3250PA__) || defined (__AVR_ATmega645__) || \
defined (__AVR_ATmega645A__) || defined (__AVR_ATmega645P__) || defined (__AVR_ATmega6450__) || \
defined (__AVR_ATmega6450A__) || defined (__AVR_ATmega6450P__) || defined (__AVR_ATmega165PA__) || \
defined (__AVR_ATmega6490__) || defined (__AVR_ATmega6490A__) || defined (__AVR_ATmega6490P__) || \
defined (__AVR_ATmega169__) || defined (__AVR_ATmega169A__) || defined (__AVR_ATmega169P__) || \
defined (__AVR_ATmega329__) || defined (__AVR_ATmega329A__) || defined (__AVR_ATmega3290P__) || \
defined (__AVR_ATmega329P__) || defined (__AVR_ATmega329PA__) || defined (__AVR_ATmega3290PA__) || \
defined (__AVR_ATmega3290__) || defined (__AVR_ATmega3290A__) || defined (__AVR_ATmega169PA__) || \
defined (__AVR_ATmega649__) || defined (__AVR_ATmega649A__) || defined (__AVR_ATmega649P__)
#undef PORTG_EXC
#define PORTG_EXC 5
#elif defined (__AVR_ATmega88PA__) || defined (__AVR_ATmega88PB__) || defined (__AVR_ATmega88P__) || \
defined (__AVR_ATmega88A__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega48P__) || \
defined (__AVR_ATmega48PB__) || defined (__AVR_ATmega48PA__) || defined (__AVR_ATmega48A__) || \
defined (__AVR_ATmega48__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8__) || \
defined (__AVR_ATmega168PA__) || defined (__AVR_ATmega168P__) || defined (__AVR_ATmega168A__) || \
defined (__AVR_ATmega168__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || \
defined (__AVR_ATtiny48__) || defined (__AVR_ATtiny88__) || defined (__AVR_ATA6612C__) || \
defined (__AVR_ATA6613C__) || defined (__AVR_ATA6614Q__)
#undef PORTC_EXC
#define PORTC_EXC 6
#elif defined (__AVR_ATtiny13__) || defined (__AVR_ATtiny13A__) || defined (__AVR_ATtiny25__) || \
defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) || defined (__AVR_ATtiny15__) || \
defined (__AVR_ATtiny12__) || defined (__AVR_ATtiny11__)
#undef PORTB_EXC
#define PORTB_EXC 5
#endif
#ifdef PORTA_EXC
#define PORTA_EXC_MASK (~(1<<(PORTA_EXC+1)))
#else
#define PORTA_EXC_MASK 0xff
#endif
#ifdef PORTB_EXC
#define PORTB_EXC_MASK (~(1<<(PORTB_EXC+1)))
#else
#define PORTB_EXC_MASK 0xff
#endif
#ifdef PORTC_EXC
#define PORTC_EXC_MASK (~(1<<(PORTC_EXC+1)))
#else
#define PORTC_EXC_MASK 0xff
#endif
#ifdef PORTD_EXC
#define PORTD_EXC_MASK (~(1<<(PORTD_EXC+1)))
#else
#define PORTD_EXC_MASK 0xff
#endif
#ifdef PORTE_EXC
#define PORTE_EXC_MASK (~(1<<(PORTE_EXC+1)))
#else
#define PORTE_EXC_MASK 0xff
#endif
#ifdef PORTF_EXC
#define PORTF_EXC_MASK (~(1<<(PORTF_EXC+1)))
#else
#define PORTF_EXC_MASK 0xff
#endif
#ifdef PORTG_EXC
#define PORTG_EXC_MASK (~(1<<(PORTG_EXC+1)))
#else
#define PORTG_EXC_MASK 0xff
#endif
#ifdef PORTH_EXC
#define PORTH_EXC_MASK (~(1<<(PORTH_EXC+1)))
#else
#define PORTH_EXC_MASK 0xff
#endif
#if PORTAN > 0
# define PORTA_MASK (((1<<PORTAN)-1)&PORTA_EXC_MASK)
#else
# define PORTA_MASK 0
#endif
#if PORTBN > 0
# define PORTB_MASK (((1<<PORTBN)-1)&PORTB_EXC_MASK)
#else
# define PORTB_MASK 0
#endif
#if PORTCN > 0
# define PORTC_MASK (((1<<PORTCN)-1)&PORTC_EXC_MASK)
#else
# define PORTC_MASK 0
#endif
#if PORTDN > 0
#define PORTD_MASK (((1<<PORTDN)-1)&PORTD_EXC_MASK)
#else
#define PORTD_MASK 0
#endif
#if PORTEN > 0
#define PORTE_MASK (((1<<PORTEN)-1)&PORTE_EXC_MASK)
#else
#define PORTE_MASK 0
#endif
#if PORTFN > 0
#define PORTF_MASK (((1<<PORTFN)-1)&PORTF_EXC_MASK)
#else
#define PORTF_MASK 0
#endif
#if PORTGN > 0
#define PORTG_MASK (((1<<PORTGN)-1)&PORTG_EXC_MASK)
#else
#define PORTG_MASK 0
#endif
#if PORTHN > 0
#define PORTH_MASK (((1<<PORTHN)-1)&PORTH_EXC_MASK)
#else
#define PORTH_MASK 0
#endif
#if PORTAN > PORTN_MAX
#undef PORTN_MAX
#define PORTN_MAX PORTAN
#endif
#if PORTBN > PORTN_MAX
#undef PORTN_MAX
#define PORTN_MAX PORTBN
#endif
#if PORTCN > PORTN_MAX
#undef PORTN_MAX
#define PORTN_MAX PORTCN
#endif
#if PORTDN > PORTN_MAX
#undef PORTN_MAX
#define PORTN_MAX PORTDN
#endif
#if PORTEN > PORTN_MAX
#undef PORTN_MAX
#define PORTN_MAX PORTEN
#endif
#if PORTFN > PORTN_MAX
#undef PORTN_MAX
#define PORTN_MAX PORTFN
#endif
#if PORTGN > PORTN_MAX
#undef PORTN_MAX
#define PORTN_MAX PORTGN
#endif
#if PORTHN > PORTN_MAX
#undef PORTN_MAX
#define PORTN_MAX PORTHN
#endif
#endif /* DEFS_H */

68
main.c
View File

@ -1,25 +1,59 @@
#include <avr/io.h> #include "defs.h"
#define F_CPU 8000000
#include <util/delay.h>
int main(void) { int main(void) {
#if defined(DDRC) && defined(DDRD) uint8_t val = 0;
#define BITS 8 #ifdef DDRA
DDRC = 0x3f; DDRA = PORTA_MASK;
DDRD = DDRB = 0xff; #endif
#else #ifdef DDRB
#define BITS 6 DDRB = PORTB_MASK;
DDRB = 0x3f; #endif
#ifdef DDRC
DDRC = PORTC_MASK;
#endif
#ifdef DDRD
DDRD = PORTD_MASK;
#endif
#ifdef DDRE
DDRE = PORTE_MASK;
#endif
#ifdef DDRF
DDRF = PORTF_MASK;
#endif
#ifdef DDRG
DDRG = PORTG_MASK;
#endif
#ifdef DDRH
DDRH = PORTH_MASK;
#endif #endif
for (;;) { for (;;) {
for (uint8_t i = 0; i < BITS; ++i) { for (uint8_t i = 0; i < PORTN_MAX; ++i) {
#if defined(DDRC) && defined(DDRD) val ^= _BV(i);
PORTC = (PORTD = PORTB ^= _BV(i))&0x3f; #ifdef DDRA
#else PORTA = val&PORTA_MASK;
PORTB ^= _BV(i);
#endif #endif
_delay_ms(36); #ifdef DDRB
PORTB = val&PORTB_MASK;
#endif
#ifdef DDRC
PORTC = val&PORTC_MASK;
#endif
#ifdef DDRD
PORTD = val&PORTD_MASK;
#endif
#ifdef DDRE
PORTE = val&PORTE_MASK;
#endif
#ifdef DDRF
PORTF = val&PORTF_MASK;
#endif
#ifdef DDRG
PORTG = val&PORTG_MASK;
#endif
#ifdef DDRH
PORTH = val&PORTH_MASK;
#endif
_delay_ms(41);
} }
} }
return 0;
} }