1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/atmega128rfa1: ATmega128rfa1 MCU support

This commit is contained in:
Benjamin Valentin 2019-09-28 00:02:16 +02:00 committed by Benjamin Valentin
parent 6617c5c768
commit 7d78e32b15
15 changed files with 502 additions and 6 deletions

View File

@ -121,7 +121,7 @@ extern "C" {
#define TIMER_1_ISRA TIMER3_COMPA_vect
#define TIMER_1_ISRB TIMER3_COMPB_vect
#define TIMER_1_ISRC TIMER3_COMPC_vect
#elif defined(CPU_ATMEGA256RFR2)
#elif defined(CPU_ATMEGA128RFA1) || defined(CPU_ATMEGA256RFR2)
#define TIMER_NUMOF (3U)
#define TIMER_CHANNELS (3)
@ -203,7 +203,8 @@ extern "C" {
*/
#ifndef UART_NUMOF
#if defined(CPU_ATMEGA256RFR2) || defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P) || defined(CPU_ATMEGA2560)
#if defined(CPU_ATMEGA128RFA1) || defined(CPU_ATMEGA256RFR2) || \
defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P) || defined(CPU_ATMEGA2560)
#define UART_NUMOF (2U)
/* UART0 is used for stdio */
@ -295,7 +296,8 @@ extern "C" {
* @{
*/
#ifndef ADC_NUMOF
#if defined(CPU_ATMEGA256RFR2) || defined(CPU_ATMEGA328P) || defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P) || defined(CPU_ATMEGA32U4)
#if defined(CPU_ATMEGA128RFA1) || defined(CPU_ATMEGA256RFR2) || defined(CPU_ATMEGA328P) || \
defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P) || defined(CPU_ATMEGA32U4)
#define ADC_NUMOF (8U)
#elif defined (CPU_ATMEGA2560)
#define ADC_NUMOF (16U)

View File

@ -0,0 +1,7 @@
# define the module that is build
MODULE = cpu
# add a list of subdirectories, that should also be build
DIRS = periph $(RIOTCPU)/atmega_common/
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,6 @@
# additional PCINTs for atmega128rfa1
ifneq (,$(filter atmega_pcint,$(USEMODULE)))
USEMODULE += atmega_pcint1
endif
include $(RIOTCPU)/atmega_common/Makefile.dep

View File

@ -0,0 +1,9 @@
include $(RIOTCPU)/atmega_common/Makefile.features
# common feature are defined in atmega_common/Makefile.features
# Only add Additional features
# additional PCINT for atmega128rfa1
FEATURES_PROVIDED += atmega_pcint1
# Various other features (if any)
FEATURES_PROVIDED += periph_cpuid

View File

@ -0,0 +1,16 @@
# tell the build system that the CPU depends on the atmega common files
USEMODULE += atmega_common
#include periph module
USEMODULE += periph
RAM_LEN = 16K
ROM_LEN = 128K
# expand atmega_pcint for atmega128rfa1
ifneq (,$(filter atmega_pcint,$(USEMODULE)))
USEMODULE += atmega_pcint1
endif
# CPU depends on the atmega common module, so include it
include $(RIOTCPU)/atmega_common/Makefile.include

View File

@ -0,0 +1,5 @@
/**
* @defgroup cpu_atmega128rfa1 Atmel ATmega128rfa1
* @ingroup cpu
* @brief Implementation of Atmel's ATmega128rfa1 MCU
*/

View File

@ -0,0 +1,15 @@
#ifndef ATMEGA_PCINT_H
#define ATMEGA_PCINT_H
#ifdef __cplusplus
extern "C" {
#endif
#define ATMEGA_PCINT_MAP_PCINT0 GPIO_PIN(PORT_B, 0), GPIO_PIN(PORT_B, 1), GPIO_PIN(PORT_B, 2), GPIO_PIN(PORT_B, 3), GPIO_PIN(PORT_B, 4), GPIO_PIN(PORT_B, 5), GPIO_PIN(PORT_B, 6), GPIO_PIN(PORT_B, 7)
#define ATMEGA_PCINT_MAP_PCINT1 GPIO_PIN(PORT_E, 0), GPIO_UNDEF, GPIO_UNDEF, GPIO_UNDEF, GPIO_UNDEF, GPIO_UNDEF, GPIO_UNDEF, GPIO_UNDEF
#ifdef __cplusplus
}
#endif
#endif /* ATMEGA_PCINT_H */

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) Josua Arndt, Steffen Robertz 2017 RWTH Aachen
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_atmega128rfa1
* @{
*
* @file
* @brief CPU specific definitions for internal peripheral handling
*
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
*/
#ifndef PERIPH_CPU_H
#define PERIPH_CPU_H
#include "periph_cpu_common.h"
#include "atmega_regs_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Length of the CPU_ID in octets
* @{
*/
#define CPUID_LEN (8U)
/** @} */
/**
* @name Available ports on the ATmega128rfa1 MCU
* @{
*/
enum {
PORT_B = 1, /**< port B */
PORT_D = 3, /**< port D */
PORT_E = 4, /**< port E */
PORT_F = 5, /**< port F */
PORT_G = 6, /**< port G */
};
/**
* @brief Available external interrupt pins on the ATmega128rfa1 MCU
*
* In order of their interrupt number.
*/
#define CPU_ATMEGA_EXT_INTS { GPIO_PIN(PORT_D, 0), \
GPIO_PIN(PORT_D, 1), \
GPIO_PIN(PORT_D, 2), \
GPIO_PIN(PORT_D, 3), \
GPIO_PIN(PORT_E, 4), \
GPIO_PIN(PORT_E, 5), \
GPIO_PIN(PORT_E, 6), \
GPIO_PIN(PORT_E, 7) }
/**
* @name Defines for the I2C interface
* @{
*/
#define I2C_PORT_REG PORTD
#define I2C_PIN_MASK (1 << PORTD1) | (1 << PORTD0)
/** @} */
/**
* @name EEPROM configuration
* @{
*/
#define EEPROM_SIZE (4096U) /* 4kB */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* PERIPH_CPU_H */
/** @} */

View File

@ -0,0 +1,14 @@
avr linkerscript
================
Starting from avr-binutils 2.26, the linker defines symbol that can be
overriden to configure ROM and RAM length.
This ldscript is used for supporting older versions on avr-binutils like on
ubuntu xenial.
Generated by extracting the output of
avr-gcc -Wl,--verbose -mmcu=$(CPU)
With avr-binutils 2.26

View File

@ -0,0 +1,262 @@
/* Script for -n: mix text and data on same page */
/* Copyright (C) 2014-2015 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:51)
__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xff00;
__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K;
__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K;
__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K;
__SIGNATURE_REGION_LENGTH__ = DEFINED(__SIGNATURE_REGION_LENGTH__) ? __SIGNATURE_REGION_LENGTH__ : 1K;
__USER_SIGNATURE_REGION_LENGTH__ = DEFINED(__USER_SIGNATURE_REGION_LENGTH__) ? __USER_SIGNATURE_REGION_LENGTH__ : 1K;
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
data (rw!x) : ORIGIN = 0x800200, LENGTH = __DATA_REGION_LENGTH__
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
lock (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__
signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__
user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
}
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
}
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
}
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
}
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
}
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
}
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
/* Internal text space or external memory. */
.text :
{
*(.vectors)
KEEP(*(.vectors))
/* For data that needs to reside in the lower 64k of progmem. */
*(.progmem.gcc*)
/* PR 13812: Placing the trampolines here gives a better chance
that they will be in range of the code that uses them. */
. = ALIGN(2);
__trampolines_start = . ;
/* The jump trampolines for the 16-bit limited relocs will reside here. */
*(.trampolines)
*(.trampolines*)
__trampolines_end = . ;
/* avr-libc expects these data to reside in lower 64K. */
*libprintf_flt.a:*(.progmem.data)
*libc.a:*(.progmem.data)
*(.progmem*)
. = ALIGN(2);
/* For future tablejump instruction arrays for 3 byte pc devices.
We don't relax jump/call instructions within these sections. */
*(.jumptables)
*(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
__ctors_start = . ;
*(.ctors)
__ctors_end = . ;
__dtors_start = . ;
*(.dtors)
__dtors_end = . ;
KEEP(SORT(*)(.ctors))
KEEP(SORT(*)(.dtors))
/* From this point on, we don't bother about wether the insns are
below or above the 16 bits boundary. */
*(.init0) /* Start here after reset. */
KEEP (*(.init0))
*(.init1)
KEEP (*(.init1))
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init2))
*(.init3)
KEEP (*(.init3))
*(.init4) /* Initialize data and BSS. */
KEEP (*(.init4))
*(.init5)
KEEP (*(.init5))
*(.init6) /* C++ constructors. */
KEEP (*(.init6))
*(.init7)
KEEP (*(.init7))
*(.init8)
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
*(.text)
. = ALIGN(2);
*(.text.*)
. = ALIGN(2);
*(.fini9) /* _exit() starts here. */
KEEP (*(.fini9))
*(.fini8)
KEEP (*(.fini8))
*(.fini7)
KEEP (*(.fini7))
*(.fini6) /* C++ destructors. */
KEEP (*(.fini6))
*(.fini5)
KEEP (*(.fini5))
*(.fini4)
KEEP (*(.fini4))
*(.fini3)
KEEP (*(.fini3))
*(.fini2)
KEEP (*(.fini2))
*(.fini1)
KEEP (*(.fini1))
*(.fini0) /* Infinite loop after program termination. */
KEEP (*(.fini0))
_etext = . ;
} > text
.data :
{
PROVIDE (__data_start = .) ;
*(.data)
*(.data*)
*(.rodata) /* We need to include .rodata here if gcc is used */
*(.rodata*) /* with -fdata-sections. */
*(.gnu.linkonce.d*)
. = ALIGN(2);
_edata = . ;
PROVIDE (__data_end = .) ;
} > data AT> text
.bss ADDR(.data) + SIZEOF (.data) : AT (ADDR (.bss))
{
PROVIDE (__bss_start = .) ;
*(.bss)
*(.bss*)
*(COMMON)
PROVIDE (__bss_end = .) ;
} > data
__data_load_start = LOADADDR(.data);
__data_load_end = __data_load_start + SIZEOF(.data);
/* Global data not cleared after reset. */
.noinit ADDR(.bss) + SIZEOF (.bss) : AT (ADDR (.noinit))
{
PROVIDE (__noinit_start = .) ;
*(.noinit*)
PROVIDE (__noinit_end = .) ;
_end = . ;
PROVIDE (__heap_start = .) ;
} > data
.eeprom :
{
/* See .data above... */
KEEP(*(.eeprom*))
__eeprom_end = . ;
} > eeprom
.fuse :
{
KEEP(*(.fuse))
KEEP(*(.lfuse))
KEEP(*(.hfuse))
KEEP(*(.efuse))
} > fuse
.lock :
{
KEEP(*(.lock*))
} > lock
.signature :
{
KEEP(*(.signature*))
} > signature
.user_signatures :
{
KEEP(*(.user_signatures*))
} > user_signatures
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
}

View File

@ -0,0 +1 @@
include $(RIOTMAKE)/periph.mk

View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2018 RWTH Aachen, Josua Arndt, Steffen Robertz
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_atmega128rfa1
* @{
*
* @file
* @brief Low-level CPUID driver implementation
*
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
*
* @}
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "periph/cpuid.h"
#include "atmega_regs_common.h"
#include "avr/boot.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
/**
* @brief CPU_ID build from MCU register
*
* CPIUD is taken from MCU Control Register and Signature bytes.
* CPUID: 1e a8 02 1f 94 03 ff ff
* CPUID: 1e a8 02 1f 94 92 XX XX
* MEGA62/128/256_RFR2 [MANUAL] p.505
* MEGA62/128/256_RFR2 [MANUAL] p.138
* MEGA62/128/256_RFR2 [MANUAL] p.492
*
* usr_sign_0/1 are configurable values on flash page 1.
*/
void cpuid_get(void *id)
{
uint8_t signature_0 = boot_signature_byte_get(0x00);
uint8_t signature_1 = boot_signature_byte_get(0x02);
uint8_t signature_2 = boot_signature_byte_get(0x04);
uint8_t usr_sign_0 = boot_signature_byte_get(0x0100);
uint8_t usr_sign_1 = boot_signature_byte_get(0x0102);
uint8_t addr[CPUID_LEN] = {
signature_0, /* 0x1E Atmel manufacturer ID */
signature_1, /* 0xA8 Part Number high byte */
signature_2, /* 0x02 Part Number low byte */
MAN_ID_0, /* 0x1F Atmel JEDEC manufacturer ID */
PART_NUM, /* 0x94 PART_NUM Identification */
VERSION_NUM, /* 0x02 VERSION_NUM Identification */
/* last two bytes can be set to flash page 1. for differentiation of different boards */
usr_sign_0, /* user signature 0 */
usr_sign_1, /* user signature 1 */
};
#if defined(ENABLE_DEBUG)
DEBUG("CPUID: " );
for (uint8_t i=0; i<CPUID_LEN; i++)
{
DEBUG(" %02x ", addr[i] );
}
DEBUG("\n" );
#endif
memcpy( id , addr, CPUID_LEN);
}

View File

@ -170,7 +170,7 @@ ISR(BADISR_vect)
"STOP Execution.\n"));
}
#if defined (CPU_ATMEGA256RFR2)
#if defined(CPU_ATMEGA128RFA1) || defined (CPU_ATMEGA256RFR2)
ISR(BAT_LOW_vect, ISR_BLOCK)
{
__enter_isr();

View File

@ -114,7 +114,7 @@ int adc_sample(adc_t line, adc_res_t res)
#if defined(CPU_ATMEGA328P) || defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P) || defined(CPU_ATMEGA32U4)
ADMUX &= 0xf0;
ADMUX |= line;
#elif defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA256RFR2)
#elif defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA128RFA1) || defined(CPU_ATMEGA256RFR2)
if (line < 8) {
ADCSRB &= ~(1 << MUX5);
ADMUX &= 0xf0;

View File

@ -62,7 +62,7 @@ void spi_init_pins(spi_t bus)
#if defined (CPU_ATMEGA1284P)
DDRB |= ((1 << DDB4) | (1 << DDB5) | (1 << DDB7));
#endif
#if defined (CPU_ATMEGA256RFR2)
#if defined(CPU_ATMEGA128RFA1) || defined(CPU_ATMEGA256RFR2)
/* Master: PB3 MISO set to out
* PB2 MOSI set to input by hardware
* PB1 SCK set to out