arch/avr/avrdx: initial support for AVRnDx chips

Initial support adds chip specific files like Kconfig, flags for the compiler,
and basic functionality like system timer. Some files are stubs derived
from corresponding ATmega files but without the functionality they are
supposed to add (to be done in later patches)

Part of the work is altered copies of corresponding files for ATMega MCUs.

Initially supported is AVR128DA28.
This commit is contained in:
Kerogit 2025-03-10 22:23:42 +01:00 • committed by Xiang Xiao
parent 100bbe620e
commit 66f6bb45ab
21 changed files with 1886 additions and 7 deletions

View file

@ -0,0 +1,28 @@
======================
Microchip DA/DB family
======================
This is an attempt to support AVR DA/DB family of MCUs
Clock Configuration
===================
The chip features internal high frequency oscillator, its frequency
can be set in the Kconfig-based configuration. Clock speed in MHz
is then provided in CONFIG_AVRDX_HFO_CLOCK_FREQ
System Timer
============
System timer is provided by RTC peripheral and takes over it. (In theory,
the Periodic Interrupt - PIT - component of it can be still used
but they share single clock.)
Supported Boards
================
.. toctree::
:glob:
:maxdepth: 1
boards/*/*

View file

@ -0,0 +1,118 @@
===========================
Notes on AVR context switch
===========================
This document describes the ways and circumstances in which context
switches happen in AVR MCUs.
Used terms and context switch basics
====================================
Context creation
----------------
There are two ways context is created when a task is suspended.
Either the task is suspended in response to a hardware interrupt
(context created ``in-interrupt`` in the following text), or it is
suspended voluntarily, eg. by calling sleep(), read() etc.
(``in-task`` context.)
The resulting context is identical and interchangeable with two differences:
- ``SREG`` - ``in-interrupt`` context has global interrupt enabled ("I"-flag) set
- position in the program where the task resumes running (arbitrary point for ``in-interrupt`` vs. inside ``up_switch_context()`` for ``in-task``
Task resumption
---------------
Task can be resumed in two corresponding situations - context switch
in response to a hardware interrupt (``by-interrupt``) or in response
to other task relinquishing the CPU (``by-task``)
Context switch
==============
Two ways of context creation combined with two ways of task resumption
give 4 possibilities of context switch process, two of which are
not interesting:
1st combination
---------------
``in-task`` context resumed in ``by-task`` context switch. Context
to be resumed has "I" flag cleared and SREG is restored with that flag cleared.
The ``ret`` instruction is used to resume the task,"returning" to the point
where it gave the CPU up, which is inside ``up_switch_context()``.
This function is supposed to be executed with interrupt disabled ("This
function is called only from the NuttX scheduling logic. Interrupts
will always be disabled when this function is
called." https://nuttx.apache.org/docs/latest/reference/os/arch.html ) Caller
of the context switch method is therefore responsible
for re-enabling interrupts.
2nd
---
``in-interrupt`` resumed in ``by-interrupt`` context switch. The task
essentially (from its point of view) exits interrupt handler after
it entered it. Instruction ``reti`` is used to return from the handler,
setting "I"-flag in the process.
3rd
---
Third and fourth combinations are more interesting:
``in-task`` context resumed in ``by-interrupt``. The CPU enters
ISR and regular program flow requires returning from ISR and setting
"I"-flag by ``reti`` which does not happen. Task is resumed with
interrupts disabled. However, it is resumed inside ``up_switch_context()``
and caller of that function will set the "I"-flag at some point.
Task then runs with interrupts enabled, all is well.
4th
---
``in-interrupt`` resumed in ``by-task``, ie. in ``up_switch_context()``.
``reti`` is used to resume the task, setting "I"-flag in the process.
This would be incorrect for ``up_switch_context()`` - it is supposed
to run with interrupts disabled - but the task resumes running
from the point where it was interrupted, which is not inside
of ``up_switch_context()``. All is well.
AVRDx core considerations
=========================
Now, all of the above holds true for eg. ATmega chips which control
interrupt execution solely by the "I"-flag, allowing the code
to not care about where the context switch was triggered. Regardless
of that, the MCU will always end up in correct state even if the
context switch cause doesn't match the context being restored
(cases 3 and 4.)
This is not the case for AVR Dx family which behaves differently.
The interrupt controller does respect the "I"-flag in a sense where
it considers interrupts disabled when the flag is cleared. However,
it is possible that interrupts are not enabled when the flag is set.
That depends on a logical AND between "I"-flag and "interrupt handler
is not executing" internal state. (Refer to the documentation
for more precise explanation.)
What this means is that if eg. ``in-task`` context gets
resumed in ``by-interrupt`` condition (case 3 above), then ``ret``
instruction is used
to resume the task. As discussed above, the "I"-flag is not set this
way but that is not a problem, it is eventually set later. However,
the internal state "running the interrupt handler" is not cleared.
This means that the task keeps running with "global interrupts are
enabled" but is actually unable to be interrupted. The context switch
code needs to handle this.
Conversely, there is a similar problem with ``in-interrupt`` context
being resumed in ``by-task`` (case 4). Instruction ``reti`` is used
but there is no internal state to be cleared. Unlike the previous case,
no problem related to this was observed but it still looks like something
the code wants to avoid. It could trigger all sorts of undefined behaviour
in the chip otherwise.

View file

@ -23,6 +23,13 @@ config ARCH_CHIP_AT90USB
---help---
Atmel AT90USB family of 8-bit AVRs.
config ARCH_CHIP_AVRDX
bool "AVR 32/64/128 DA/DB core"
select ARCH_FAMILY_AVR
select MM_SMALL
---help---
Atmel/Microchip AVR 32/64/128 DA/DB core family.
config ARCH_CHIP_AT32UC3
bool "AVR32 AT32UC3* family"
select ARCH_FAMILY_AVR32
@ -54,6 +61,7 @@ config ARCH_FAMILY
config ARCH_CHIP
string
default "atmega" if ARCH_CHIP_ATMEGA
default "avrdx" if ARCH_CHIP_AVRDX
default "at90usb" if ARCH_CHIP_AT90USB
default "at32uc3" if ARCH_CHIP_AT32UC3
@ -63,6 +71,7 @@ if ARCH_FAMILY_AVR
source "arch/avr/src/avr/Kconfig"
source "arch/avr/src/at90usb/Kconfig"
source "arch/avr/src/atmega/Kconfig"
source "arch/avr/src/avrdx/Kconfig"
endif
if ARCH_FAMILY_AVR32

View file

@ -0,0 +1,143 @@
/****************************************************************************
* arch/avr/include/avrdx/irq.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/* This file should never be included directly but, rather, only indirectly
* through nuttx/irq.h
*/
#ifndef __ARCH_AVR_INCLUDE_AVRDX_IRQ_H
#define __ARCH_AVR_INCLUDE_AVRDX_IRQ_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/irq.h>
#include <arch/avr/avr.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* AVRnDx interrupt vectors other than vector 0, the reset vector, are
* assigned here:
*/
#if defined(CONFIG_ARCH_CHIP_AVR128DA28)
# define AVRDX_IRQ_NMI 0 /* Non-maskable interrupt */
# define AVRDX_IRQ_BOD_VLM 1 /* BOD interrupt */
# define AVRDX_IRQ_RTC_CNT 2 /* RTC and periodic interrupt */
# define AVRDX_IRQ_RTC_PIT 3
# define AVRDX_IRQ_CCL_CCL 4 /* CCL */
# define AVRDX_IRQ_PORTA_PORT 5 /* PORTA interrupts */
# define AVRDX_IRQ_TCA0_LUNF 6 /* TIMER A0 Low byte underflow */
# define AVRDX_IRQ_TCA0_OVF 6
# define AVRDX_IRQ_TCA0_HUNF 7 /* TIMER A0 High byte underflow */
# define AVRDX_IRQ_TCA0_CMP0 8 /* TIMER A0 compare match 0 */
# define AVRDX_IRQ_TCA0_LCMP0 8 /* TIMER A0 Low byte compare match 0 */
# define AVRDX_IRQ_TCA0_CMP1 9
# define AVRDX_IRQ_TCA0_LCMP1 9
# define AVRDX_IRQ_TCA0_CMP2 10
# define AVRDX_IRQ_TCA0_LCMP2 10
# define AVRDX_IRQ_TCB0_INT 11
# define AVRDX_IRQ_TCB1_INT 12
# define AVRDX_IRQ_TCD0_OVF 13
# define AVRDX_IRQ_TCD0_TRIG 14
# define AVRDX_IRQ_TWI0_TWIS 15 /* TWI client interrupt */
# define AVRDX_IRQ_TWI0_TWIM 16 /* TWI host interrupt */
# define AVRDX_IRQ_SPI0_INT 17
# define AVRDX_IRQ_USART0_RXC 18
# define AVRDX_IRQ_USART0_DRE 19
# define AVRDX_IRQ_USART0_TXC 20
# define AVRDX_IRQ_PORTD_PORT 21
# define AVRDX_IRQ_AC0_AC 22 /* AC0 analog comparator interrupt */
# define AVRDX_IRQ_ADC0_RESRDY 23 /* ADC0 result ready */
# define AVRDX_IRQ_ADC0_WCMP 24 /* ADC0 Window compare interrupt */
# define AVRDX_IRQ_ZCD0_ZCD 25 /* Zero-cross interrupt */
# define AVRDX_IRQ_PTC_PTC 26 /* Peripheral touch controller interrupt */
# define AVRDX_IRQ_AC1_AC 27
# define AVRDX_IRQ_PORTC_PORT 28
# define AVRDX_IRQ_TCB2_INT 29
# define AVRDX_IRQ_USART1_RXC 30
# define AVRDX_IRQ_USART1_DRE 31
# define AVRDX_IRQ_USART1_TXC 32
# define AVRDX_IRQ_PORTF_PORT 33
# define AVRDX_IRQ_NVMCTRL_EE 34 /* NVM controller EEPROM ready interrupt */
# define AVRDX_IRQ_SPI1_INT 35
# define AVRDX_IRQ_USART2_RXC 36
# define AVRDX_IRQ_USART2_DRE 37
# define AVRDX_IRQ_USART2_TXC 38
# define AVRDX_IRQ_AC2_AC 39
# define NR_IRQS 40
# define AVR_PC_SIZE 16
# define XCPTCONTEXT_REGS 38 /* Size of the register state save array (in bytes),
* 32B registers + 1B SREG + 2B PC + 2B SP (?)
* +1B RAMPZ
*/
# if defined(CONFIG_AVR_HAS_RAMPZ)
# define AVR_HAS_RAMPZ
# else
# error CONFIG_AVR_HAS_RAMPZ is supposed to be set for this chip
# endif
#else
#error "Unrecognized chip"
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Inline functions
****************************************************************************/
#ifndef __ASSEMBLY__
#endif /* __ASSEMBLY__ */
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif
#endif /* __ARCH_AVR_INCLUDE_AVRDX_IRQ_H */

View file

@ -67,6 +67,9 @@ ifeq ($(CONFIG_ARCH_CHIP_ATMEGA128),y)
else ifeq ($(CONFIG_ARCH_CHIP_ATMEGA1284P),y)
ARCHCPUFLAGS += -mmcu=atmega1284p
LDFLAGS += -mavr51
else ifeq ($(CONFIG_ARCH_CHIP_AVR128DA28),y)
ARCHCPUFLAGS += -mmcu=avr128da28
LDFLAGS += -mavrxmega4
else ifeq ($(CONFIG_ARCH_CHIP_AT90USB646),y)
ARCHCPUFLAGS += -mmcu=at90usb646
LDFLAGS += -mavr5

View file

@ -428,6 +428,19 @@
/* Save the return address that we have saved in r18:19 */
/* Note - this seems backwards for AVR DA/DB family which
* states in the docs, chapter 6.4.4: The return address
* consists of two bytes and the Least Significant Byte (LSB)
* is pushed on the stack first (at the higher address).
*
* First value is popped into r19 and holds the MSB, store
* ordering is reversed here.
*
* Considering this value is just stored and then restored
* with the same discrepancy, it cancels out. No need to branch
* the code with ifdefs.
*/
#if AVR_PC_SIZE > 16
st x+, r20
#endif /* AVR_PC_SIZE */
@ -578,12 +591,33 @@
/* If interrupts shall be enabled go to 'restore remaining and reti' code
* otherwise just do 'restore remaining and ret'
*
* See Documentation/platforms/avr/context-switch-notes.rst
* for information about context creation and how it interacts
* with ways the context is restored
*/
ld r24, x+
bst r24, SREG_I
brts go_reti
#ifdef CONFIG_ARCH_CHIP_AVRDX
/* Older chips do not care for internal MCU state here but for AVR Dx
* family, we need to do different things based on if we came here
* from interrupt handler or not.
*
* We do all branching now because at this point we are about to restore
* SREG, don't have free registers to preserve it anymore and branching
* would clobber it
*
* Branch away if we came here from interrupt handler
*/
lds r25, CPUINT_STATUS
and r25, r25
brne .tcbr_avrdx_ret_reti
#endif
/* Restore the status register, interrupts are disabled */
out _SFR_IO_ADDR(SREG), r24
@ -602,12 +636,71 @@
pop r26
ret
#ifdef CONFIG_ARCH_CHIP_AVRDX
.tcbr_avrdx_ret_reti:
/* See branch above for more detailed comments */
out _SFR_IO_ADDR(SREG), r24 /* SREG with I-flag cleared */
/* Restore r24-r25 - The temporary and IRQ number registers */
ld r25, x+ /* restore r24-r25 */
ld r24, x+
pop r27 /* recovering R27 then R26 */
pop r26
/* Returning with I-flag cleared (reti does not change that),
* but clearing internal "running in interrupt context" state
*/
reti
#endif
go_reti:
#ifdef CONFIG_ARCH_CHIP_AVRDX
/* In this case, branch away if we did NOT come here
* from an interrupt handler
*/
lds r25, CPUINT_STATUS
and r25, r25
breq .tcbr_avrdx_reti_ret
#endif
#ifdef CONFIG_ARCH_CHIP_AVRDX
/* restore Status Register with interrupt enabled. Hardware
* knows it is processing an interrupt and will not interrupt
* us even with "I"-flag set (With the exception of high
* priority interrupts but those are not supported.)
*/
#else
/* restore the Status Register with interrupts disabled
* and exit with reti (that will set the Interrupt Enable)
*/
andi r24, ~(1 << SREG_I)
#endif
out _SFR_IO_ADDR(SREG), r24
ld r25, x+
ld r24, x+
pop r27
pop r26
reti
#ifdef CONFIG_ARCH_CHIP_AVRDX
.tcbr_avrdx_reti_ret:
/* restore the Status Register with interrupts disabled,
* we don't want to be interrupted until done
*/
andi r24, ~(1 << SREG_I)
out _SFR_IO_ADDR(SREG), r24
ld r25, x+
@ -616,7 +709,18 @@ go_reti:
pop r27
pop r26
reti
/* Now enable interrupts and exit with ret, not messing with internal
* state of the interrupt controller because from its point of view,
* we are not returning from interrupt (despite the fact that the restored
* context was created in an interrupt)
*
* AVR Instruction Set Manual DS40002198 states: "The instruction
* following SEI will be executed before any pending interrupts."
*/
sei
ret
#endif
.endm

View file

@ -0,0 +1,90 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
if ARCH_CHIP_AVRDX
comment "AVR DA/DB Configuration Options"
choice
prompt "Atmel AVR DA/DB chip selection"
default ARCH_CHIP_AVR128DA28
config ARCH_CHIP_AVR128DA28
bool "AVR128DA28"
select AVR_HAS_RAMPZ
---help---
Atmel AVR128DA28 8-bit AVR.
endchoice # AVR DA/DB Configuration Options
menu "AVR DA/DB Peripheral Selections"
# TBD
endmenu # AVR DA/DB Peripheral Selections
choice
prompt "Internal High-Frequency Oscillator clock speed"
default AVRDX_HFO_CLOCK_24MHZ
config AVRDX_HFO_CLOCK_1MHZ
bool "1MHz"
---help---
Internal oscillator set to 1MHz
config AVRDX_HFO_CLOCK_2MHZ
bool "2MHz"
---help---
Internal oscillator set to 2MHz
config AVRDX_HFO_CLOCK_3MHZ
bool "3MHz"
---help---
Internal oscillator set to 3MHz
config AVRDX_HFO_CLOCK_4MHZ
bool "4MHz"
---help---
Internal oscillator set to 4MHz
config AVRDX_HFO_CLOCK_8MHZ
bool "8MHz"
---help---
Internal oscillator set to 8MHz
config AVRDX_HFO_CLOCK_12MHZ
bool "12MHz"
---help---
Internal oscillator set to 12MHz
config AVRDX_HFO_CLOCK_16MHZ
bool "16MHz"
---help---
Internal oscillator set to 16MHz
config AVRDX_HFO_CLOCK_20MHZ
bool "20MHz"
---help---
Internal oscillator set to 20MHz
config AVRDX_HFO_CLOCK_24MHZ
bool "24MHz"
---help---
Internal oscillator set to 24MHz
endchoice
config AVRDX_HFO_CLOCK_FREQ
int
default 1000000 if AVRDX_HFO_CLOCK_1MHZ
default 2000000 if AVRDX_HFO_CLOCK_2MHZ
default 3000000 if AVRDX_HFO_CLOCK_3MHZ
default 4000000 if AVRDX_HFO_CLOCK_4MHZ
default 8000000 if AVRDX_HFO_CLOCK_8MHZ
default 12000000 if AVRDX_HFO_CLOCK_12MHZ
default 16000000 if AVRDX_HFO_CLOCK_16MHZ
default 20000000 if AVRDX_HFO_CLOCK_20MHZ
default 24000000 if AVRDX_HFO_CLOCK_24MHZ
endif

View file

@ -0,0 +1,58 @@
############################################################################
# arch/avr/src/avrdx/Make.defs
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
# The start-up, "head", file
HEAD_ASRC = avrdx_head.S
# Common AVR files
CMN_ASRCS = avr_doswitch.S avr_saveusercontext.S
CMN_CSRCS = avr_allocateheap.c avr_copystate.c avr_createstack.c
CMN_CSRCS += avr_doirq.c avr_exit.c avr_idle.c avr_initialize.c
CMN_CSRCS += avr_initialstate.c avr_irq.c avr_lowputs.c avr_mdelay.c
CMN_CSRCS += avr_nputs.c avr_releasestack.c avr_registerdump.c
CMN_CSRCS += avr_schedulesigaction.c avr_sigdeliver.c avr_getintstack.c
CMN_CSRCS += avr_stackframe.c avr_udelay.c avr_switchcontext.c avr_usestack.c
# Configuration-dependent common files
ifeq ($(CONFIG_AVR_SPI),y)
CMN_CSRCS += avr_spi.c
endif
ifeq ($(CONFIG_STACK_COLORATION),y)
CMN_CSRCS += avr_checkstack.c
endif
ifeq ($(CONFIG_ARCH_ROMGETC),y)
CMN_CSRCS += avr_romgetc.c
endif
# Required AVRnDx files
CHIP_ASRCS = avrdx_exceptions.S
CHIP_CSRCS = avrdx_lowconsole.c avrdx_lowinit.c avrdx_serial.c
ifneq ($(CONFIG_SCHED_TICKLESS),y)
CHIP_CSRCS += avrdx_timerisr.c
endif

107
arch/avr/src/avrdx/avrdx.h Normal file
View file

@ -0,0 +1,107 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_AVR_SRC_AVRDX_AVRDX_H
#define __ARCH_AVR_SRC_AVRDX_AVRDX_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "avrdx_config.h"
#include <stdint.h>
#include <stdbool.h>
#include "avrdx_iodefs.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: up_clkinit
*
* Description:
* Initialize clock/PLL settings per the definitions in the board.h file.
*
****************************************************************************/
void up_clkinitialize(void);
/****************************************************************************
* Name: up_consoleinit
*
* Description:
* Initialize a console for debug output. This function is called very
* early in the initialization sequence to configure the serial console
* uart (only).
*
****************************************************************************/
void up_consoleinit(void);
/****************************************************************************
* Name: avrdx_boardinitialize
*
* Description:
* This function must be provided by the board-specific logic in the
* directory boards/avr/avrdx/<board-name>/src.
*
****************************************************************************/
void avrdx_boardinitialize(void);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_AVR_SRC_AVRDX_AVRDX_H */

View file

@ -0,0 +1,48 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx_config.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_AVR_SRC_AVRDX_AVRDX_CONFIG_H
#define __ARCH_AVR_SRC_AVRDX_AVRDX_CONFIG_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Functions Prototypes Prototypes
****************************************************************************/
#endif /* __ARCH_AVR_SRC_AVRDX_AVRDX_CONFIG_H */

View file

@ -0,0 +1,173 @@
/********************************************************************************************
* arch/avr/src/avrdx/avrdx_exceptions.S
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
********************************************************************************************/
/********************************************************************************************
* Included Files
********************************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include "excptmacros.h"
/********************************************************************************************
* External Symbols
********************************************************************************************/
.file "avrdx_exceptions.S"
.global avr_doirq
.global avr_fullcontextrestore
/********************************************************************************************
* Macros
********************************************************************************************/
/********************************************************************************************
* Exception Vector Handlers
********************************************************************************************/
.section .handlers, "ax", @progbits
#if defined(CONFIG_ARCH_CHIP_AVR128DA28)
HANDLER avrdx_nmi, AVRDX_IRQ_NMI, excpt_common
HANDLER avrdx_bod_vlm, AVRDX_IRQ_BOD_VLM, excpt_common
HANDLER avrdx_rtc_cnt, AVRDX_IRQ_RTC_CNT, excpt_common
HANDLER avrdx_rtc_pit, AVRDX_IRQ_RTC_PIT, excpt_common
HANDLER avrdx_ccl_ccl, AVRDX_IRQ_CCL_CCL, excpt_common
HANDLER avrdx_porta_port, AVRDX_IRQ_PORTA_PORT, excpt_common
HANDLER avrdx_tca0_ovf, AVRDX_IRQ_TCA0_OVF, excpt_common
HANDLER avrdx_tca0_hunf, AVRDX_IRQ_TCA0_HUNF, excpt_common
HANDLER avrdx_tca0_cmp0, AVRDX_IRQ_TCA0_CMP0, excpt_common
HANDLER avrdx_tca0_cmp1, AVRDX_IRQ_TCA0_CMP1, excpt_common
HANDLER avrdx_tca0_cmp2, AVRDX_IRQ_TCA0_CMP2, excpt_common
HANDLER avrdx_tcb0_int, AVRDX_IRQ_TCB0_INT, excpt_common
HANDLER avrdx_tcb1_int, AVRDX_IRQ_TCB1_INT, excpt_common
HANDLER avrdx_tcd0_ovf, AVRDX_IRQ_TCD0_OVF, excpt_common
HANDLER avrdx_tcd0_trig, AVRDX_IRQ_TCD0_TRIG, excpt_common
HANDLER avrdx_twi0_twis, AVRDX_IRQ_TWI0_TWIS, excpt_common
HANDLER avrdx_twi0_twim, AVRDX_IRQ_TWI0_TWIM, excpt_common
HANDLER avrdx_spi0_int, AVRDX_IRQ_SPI0_INT, excpt_common
HANDLER avrdx_usart0_rxc, AVRDX_IRQ_USART0_RXC, excpt_common
HANDLER avrdx_usart0_dre, AVRDX_IRQ_USART0_DRE, excpt_common
HANDLER avrdx_usart0_txc, AVRDX_IRQ_USART0_TXC, excpt_common
HANDLER avrdx_portd_port, AVRDX_IRQ_PORTD_PORT, excpt_common
HANDLER avrdx_ac0_ac, AVRDX_IRQ_AC0_AC, excpt_common
HANDLER avrdx_adc0_resrdy, AVRDX_IRQ_ADC0_RESRDY, excpt_common
HANDLER avrdx_adc0_wcmp, AVRDX_IRQ_ADC0_WCMP, excpt_common
HANDLER avrdx_zcd0_zcd, AVRDX_IRQ_ZCD0_ZCD, excpt_common
HANDLER avrdx_ptc_ptc, AVRDX_IRQ_PTC_PTC, excpt_common
HANDLER avrdx_ac1_ac, AVRDX_IRQ_AC1_AC, excpt_common
HANDLER avrdx_portc_port, AVRDX_IRQ_PORTC_PORT, excpt_common
HANDLER avrdx_tcb2_int, AVRDX_IRQ_TCB2_INT, excpt_common
HANDLER avrdx_usart1_rxc, AVRDX_IRQ_USART1_RXC, excpt_common
HANDLER avrdx_usart1_dre, AVRDX_IRQ_USART1_DRE, excpt_common
HANDLER avrdx_usart1_txc, AVRDX_IRQ_USART1_TXC, excpt_common
HANDLER avrdx_portf_port, AVRDX_IRQ_PORTF_PORT, excpt_common
HANDLER avrdx_nvmctrl_ee, AVRDX_IRQ_NVMCTRL_EE, excpt_common
HANDLER avrdx_spi1_int, AVRDX_IRQ_SPI1_INT, excpt_common
HANDLER avrdx_usart2_rxc, AVRDX_IRQ_USART2_RXC, excpt_common
HANDLER avrdx_usart2_dre, AVRDX_IRQ_USART2_DRE, excpt_common
HANDLER avrdx_usart2_txc, AVRDX_IRQ_USART2_TXC, excpt_common
HANDLER avrdx_ac2_ac, AVRDX_IRQ_AC2_AC, excpt_common
#else
# error "Unrecognized chip"
#endif
/********************************************************************************************
* Name: excpt_common
*
* Description:
* Exception Vector Handlers
*
* On Entry:
* The return PC and the saved r24 is on the stack, r24 now contains the IRQ number
*
* PC1
* PC0
* R0
* --- <- SP
*
********************************************************************************************/
excpt_common:
/* Save the remaining registers on the stack, preserving the IRQ number in r14 */
EXCPT_PROLOGUE
/* Call avr_doirq with r24 = IRQ number, r22-23 = Pointer to the save structure. The stack
* pointer currently points to the save structure (or maybe the save structure -1 since
* the push operation post-decrements -- need to REVISIT this).
*/
in r28, _SFR_IO_ADDR(SPL) /* Get the save structure pointer in a Call-saved register pair */
in r29, _SFR_IO_ADDR(SPH) /* Pointer can be obtained from the stack pointer */
adiw r28, 1 /* Remembering that push post-decrements */
movw r22, r28 /* Pass register save structure as the parameter 2 */
USE_INTSTACK rx, ry, rz /* Switch to the interrupt stack */
call avr_doirq /* Dispatch the interrupt */
RESTORE_STACK rx, ry /* Undo the operations of USE_INTSTACK */
/* up_doiq returns with r24-r25 equal to the new save structure. If no context
* switch occurred, this will be the same as the value passed to it in r22-23.
* But if a context switch occurs, then the returned value will point not at a
* stack frame, but at a register save area inside of the new task's TCB.
*/
cp r28, r24
cpc r29, r25
breq .Lnoswitch
/* A context switch has occurred, jump to avr_fullcontextrestore with r24, r25
* equal to the address of the new register save ared.
*/
jmp avr_fullcontextrestore
/* No context switch occurred.. just return off the stack */
.Lnoswitch:
EXCPT_EPILOGUE
/* Unlike eg. ATmega devices, from which this code is derived,
* Dx cores do not set Interrupt Enable on reti
*/
sei
reti
/****************************************************************************************************
* Name: g_intstackalloc
****************************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 0
.bss
.align 4
.globl g_intstackalloc
.type g_intstackalloc, object
.globl g_intstacktop
.type g_intstacktop, object
g_intstackalloc:
.skip CONFIG_ARCH_INTERRUPTSTACK
g_intstacktop:
.size g_intstackalloc, .-g_intstackalloc
#endif
.end

View file

@ -0,0 +1,288 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx_head.S
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <avr/io.h>
#include <avr/common.h>
#include <avr/sfr_defs.h>
#include <arch/irq.h>
/****************************************************************************
* Pre-processor definitions
****************************************************************************/
/* Stack is allocated just after uninitialized data and just before the heap */
#define STACKBASE (_enoinit+CONFIG_IDLETHREAD_STACKSIZE)
/* The RAMPZ register should be available for all MCUs in this family
*
* - Support for the EPLMX instructions is assumed if RAMPZ is present
* - If RAMPZ is not present, support for LPMX is assumed
*/
#define HAVE_RAMPZ 1
/****************************************************************************
* External Symbols
****************************************************************************/
.file "up_nommuhead.S"
.global __start /* Entry point */
.global _sbss /* Start of .bss. Defined by ld.script */
.global _ebss /* End of .bss. Defined by ld.script */
.global _sdata /* Start of .data section in RAM */
.global _edata /* End of .data section in RAM */
.global _eronly /* Start of .data section in FLASH */
.global _enoinit /* End of uninitilized data. Defined by ld.script */
.global avr_lowinit /* Perform low level initialization */
.global nx_start /* NuttX entry point */
.global vectortab
#if defined(CONFIG_ARCH_CHIP_AVR128DA28)
.global avrdx_nmi
.global avrdx_bod_vlm
.global avrdx_rtc_cnt
.global avrdx_rtc_pit
.global avrdx_ccl_ccl
.global avrdx_porta_port
.global avrdx_tca0_ovf
.global avrdx_tca0_hunf
.global avrdx_tca0_cmp0
.global avrdx_tca0_cmp1
.global avrdx_tca0_cmp2
.global avrdx_tcb0_int
.global avrdx_tcb1_int
.global avrdx_tcd0_ovf
.global avrdx_tcd0_trig
.global avrdx_twi0_twis
.global avrdx_twi0_twim
.global avrdx_spi0_int
.global avrdx_usart0_rxc
.global avrdx_usart0_dre
.global avrdx_usart0_txc
.global avrdx_portd_port
.global avrdx_ac0_ac
.global avrdx_adc0_resrdy
.global avrdx_adc0_wcmp
.global avrdx_zcd0_zcd
.global avrdx_ptc_ptc
.global avrdx_ac1_ac
.global avrdx_portc_port
.global avrdx_tcb2_int
.global avrdx_usart1_rxc
.global avrdx_usart1_dre
.global avrdx_usart1_txc
.global avrdx_portf_port
.global avrdx_nvmctrl_ee
.global avrdx_spi1_int
.global avrdx_usart2_rxc
.global avrdx_usart2_dre
.global avrdx_usart2_txc
.global avrdx_ac2_ac
#else
#error "Unrecognized chip"
#endif
/****************************************************************************
* Macros
****************************************************************************/
.macro vector name
jmp \name
.endm
/****************************************************************************
* Vector Table
****************************************************************************/
/* The AVR128DA28 has 41 interrupt vectors including vector 0, the reset
* vector.
*/
.section .vectors, "ax", @progbits
.func vectortab
vectortab:
jmp __start /* 0: Vector 0 is the reset vector */
#if defined(CONFIG_ARCH_CHIP_AVR128DA28)
vector avrdx_nmi
vector avrdx_bod_vlm
vector avrdx_rtc_cnt
vector avrdx_rtc_pit
vector avrdx_ccl_ccl
vector avrdx_porta_port
vector avrdx_tca0_ovf
vector avrdx_tca0_hunf
vector avrdx_tca0_cmp0
vector avrdx_tca0_cmp1
vector avrdx_tca0_cmp2
vector avrdx_tcb0_int
vector avrdx_tcb1_int
vector avrdx_tcd0_ovf
vector avrdx_tcd0_trig
vector avrdx_twi0_twis
vector avrdx_twi0_twim
vector avrdx_spi0_int
vector avrdx_usart0_rxc
vector avrdx_usart0_dre
vector avrdx_usart0_txc
vector avrdx_portd_port
vector avrdx_ac0_ac
vector avrdx_adc0_resrdy
vector avrdx_adc0_wcmp
vector avrdx_zcd0_zcd
vector avrdx_ptc_ptc
vector avrdx_ac1_ac
vector avrdx_portc_port
vector avrdx_tcb2_int
vector avrdx_usart1_rxc
vector avrdx_usart1_dre
vector avrdx_usart1_txc
vector avrdx_portf_port
vector avrdx_nvmctrl_ee
vector avrdx_spi1_int
vector avrdx_usart2_rxc
vector avrdx_usart2_dre
vector avrdx_usart2_txc
vector avrdx_ac2_ac
#else
#error "Unrecognized chip"
#endif
.endfunc
/****************************************************************************
* Reset Entry Point
****************************************************************************/
.section .init, "ax", @progbits
.func __start
__start:
/* no interrupts! Useful for software reset by jumping to address 0 */
cli
#if defined(EIND)
/* set EIND to 0, just to be sure we are sane */
out _SFR_IO_ADDR(EIND), 0 // EIND = 0x3c
#endif /* EIND */
/* Clear the zero register, clear the status register and initialize the
* IDLE thread stack
*/
clr r1
out _SFR_IO_ADDR(SREG), r1
ldi r28, lo8(STACKBASE)
ldi r29, hi8(STACKBASE)
out _SFR_IO_ADDR(SPH), r29
out _SFR_IO_ADDR(SPL), r28
/* Copy initial global data values from FLASH into RAM */
.global __do_copy_data; /* Required to suppress dragging in logic from libgcc */
__do_copy_data:
#ifdef HAVE_RAMPZ
ldi r17, hi8(_edata)
ldi r26, lo8(_sdata)
ldi r27, hi8(_sdata)
ldi r30, lo8(_eronly)
ldi r31, hi8(_eronly)
ldi r16, hh8(_eronly)
out _SFR_IO_ADDR(RAMPZ), r16
rjmp .Lcopystart
.Lcopyloop:
elpm r0, Z+
st X+, r0
.Lcopystart:
cpi r26, lo8(_edata)
cpc r27, r17
brne .Lcopyloop
#else
ldi r17, hi8(_edata)
ldi r26, lo8(_sdata)
ldi r27, hi8(_sdata)
ldi r30, lo8(_eronly)
ldi r31, hi8(_eronly)
rjmp .Lcopystart
.Lcopyloop:
lpm r0, Z+
st X+, r0
.Lcopystart:
cpi r26, lo8(_edata)
cpc r27, r17
brne .Lcopyloop
#endif
/* Clear uninitialized data */
.global __do_clear_bss; /* Required to suppress dragging in logic from libgcc */
__do_clear_bss:
ldi r17, hi8(_ebss)
ldi r26, lo8(_sbss)
ldi r27, hi8(_sbss)
rjmp .Lclearstart
.Lclearloop:
st X+, r1
.Lclearstart:
cpi r26, lo8(_ebss)
cpc r27, r17
brne .Lclearloop
/* Perform any low-level initialization */
call avr_lowinit
/* Now start NuttX */
call nx_start
jmp exit
.endfunc
/****************************************************************************
* Heap Base
****************************************************************************/
/* This global variable is unsigned long g_idle_topstack and is exported from
* here only because of its coupling to other uses of _enoinit in this file
*/
.data
.globl g_idle_topstack
.type g_idle_topstack, object
g_idle_topstack:
.word _enoinit+CONFIG_IDLETHREAD_STACKSIZE
.size g_idle_topstack, .-g_idle_topstack
.end

View file

@ -0,0 +1,76 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx_iodefs.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_AVR_SRC_AVRDX_AVRDX_IODEFS_H
#define __ARCH_AVR_SRC_AVRDX_AVRDX_IODEFS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "avrdx_config.h"
#if defined(CONFIG_ARCH_CHIP_AVR128DA28)
# include "iodefs/avr128da28.h"
#else
# error "I/O register definitions for this chip are missing"
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_AVR_SRC_AVRDX_AVRDX_H */

View file

@ -0,0 +1,92 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx_lowconsole.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "avrdx_config.h"
#include <assert.h>
#include <debug.h>
#include <arch/irq.h>
#include <arch/board/board.h>
#include <avr/io.h>
#include "avr_internal.h"
#include "avrdx.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_consoleinit
*
* Description:
* Initialize a console for debug output. This function is called very
* early in the initialization sequence to configure the serial console
* uart (only).
*
****************************************************************************/
void up_consoleinit(void)
{
}
/****************************************************************************
* Name: avr_lowputc
*
* Description:
* Output one byte on the serial console. Currently not implemented
* but required by common code
*
****************************************************************************/
void avr_lowputc(char ch)
{
}

View file

@ -0,0 +1,116 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx_lowinit.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <avr/power.h>
#include <arch/board/board.h>
#include "avrdx_config.h"
#include "avr_internal.h"
#include "avrdx.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: avr_lowinit
*
* Description:
* This performs basic initialization of the hardware, notably sets main
* clock and configures USART used for the serial console etc. (USART is
* configured early to make the console output available as soon
* as possible.)
*
*
****************************************************************************/
void avr_lowinit(void)
{
/* Set the system clock */
#if (CONFIG_AVRDX_HFO_CLOCK_FREQ == 24000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_24M_GC));
#elif (CONFIG_AVRDX_HFO_CLOCK_FREQ == 20000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_20M_GC));
#elif (CONFIG_AVRDX_HFO_CLOCK_FREQ == 16000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_16M_GC));
#elif (CONFIG_AVRDX_HFO_CLOCK_FREQ == 12000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_12M_GC));
#elif (CONFIG_AVRDX_HFO_CLOCK_FREQ == 8000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_8M_GC));
#elif (CONFIG_AVRDX_HFO_CLOCK_FREQ == 4000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_4M_GC));
#elif (CONFIG_AVRDX_HFO_CLOCK_FREQ == 3000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_3M_GC));
#elif (CONFIG_AVRDX_HFO_CLOCK_FREQ == 2000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_2M_GC));
#elif (CONFIG_AVRDX_HFO_CLOCK_FREQ == 1000000)
_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,
((CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_GM)) | CLKCTRL_FRQSEL_1M_GC));
#else
/* At some point, add support to have the board supply
* its own clock setting (ie. support external clock)
*/
# error Unsupported frequency
#endif
/* Perform board-level initialization */
avrdx_boardinitialize();
}

View file

@ -0,0 +1,48 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx_memorymap.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_AVR_SRC_AVRDX_AVRDX_MEMORYMAP_H
#define __ARCH_AVR_SRC_AVRDX_AVRDX_MEMORYMAP_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Functions Prototypes
****************************************************************************/
#endif /* __ARCH_AVR_SRC_AVRDX_AVRDX_MEMORYMAP_H */

View file

@ -0,0 +1,50 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx_serial.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: up_putc
*
* Description:
* Provide priority, low-level access to support OS debug writes
* (Not yet implemented)
*
****************************************************************************/
void up_putc(int ch)
{
}

View file

@ -0,0 +1,164 @@
/****************************************************************************
* arch/avr/src/avrdx/avrdx_timerisr.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <time.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include <avr/io.h>
#include "avr_internal.h"
#include "avrdx.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* The system timer is clocked from 32kHz internal oscillator
* with a period of 61us. (Using division by 2 in case oscillator
* correction is used at some point.)
*
* For this clock frequency, the shortest period we can support
* with no errors is 15625us, 64Hz. Multiplies of this value will
* also lead to timer with no errors.
*/
#define RTC_PER_VAL ((CONFIG_USEC_PER_TICK * 16384ul / 1000000ul) - 1)
/****************************************************************************
* Forward declarations
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Function: avrdx_timerisr
*
* Description:
* The timer ISR will perform a variety of services for various portions
* of the systems.
*
****************************************************************************/
static int avrdx_timerisr(int irq, uint32_t *regs, FAR void *arg)
{
RTC.INTFLAGS = (RTC_OVF_bm | RTC_CMP_bm);
nxsched_process_timer();
return 0;
}
/****************************************************************************
* Function: avrdx_rtc_await_nobusy
*
* Description:
* RTC peripheral runs asynchronously from main clock, writes to some
* registers take time to synchronize and subsequent writes will
* not take effect.
*
* This method reads RTC.STATUS and spins until the requested register
* isn't busy.
*
* If instructed, it will also enable and disable interrupts while
* spinning so at least something can run, this is otherwise quite
* multitasking-unfriendly
*
****************************************************************************/
void avrdx_rtc_await_nobusy(uint8_t wait_flag, irqstate_t irqstate)
{
while (RTC.STATUS & wait_flag)
{
up_irq_restore(irqstate); /* Might not actually enable interrupts
* based on irqstate contents */
asm volatile("nop"); /* Why not, we are waiting for 2 ticks
* of 32768Hz clock anyway */
up_irq_save();
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: up_timer_initialize
*
* Description:
* This function is called during start-up to initialize the system timer.
*
****************************************************************************/
void up_timer_initialize(void)
{
irqstate_t irqstate;
/* Setup RTC timer
*/
irqstate = up_irq_save();
/* RTC initialization procedure as per docs:
* 1. Configure desired oscillator in Clock Controller
* (Using OSC32K which is preconfigured. Done.)
* 2. Write RTC.CLKSEL clock select field.
* (Using OSC32K which is preconfigured. Done.)
* 3. Write compare and period registers.
*/
avrdx_rtc_await_nobusy(RTC_PERBUSY_bm, \
irqstate); /* Break the line to make nxstyle happy */
RTC.PER = RTC_PER_VAL;
/* 4. Enable desired interrupts */
RTC.INTCTRL |= (RTC_OVF_bm);
/* 5. Configure prescaler */
avrdx_rtc_await_nobusy(RTC_CTRLABUSY_bm, \
irqstate);
RTC.CTRLA = (RTC.CTRLA & ~RTC_PRESCALER_GM) | RTC_PRESCALER_DIV2_GC;
/* 6. Enable the RTC */
avrdx_rtc_await_nobusy(RTC_CTRLABUSY_bm, \
irqstate);
RTC.CTRLA |= RTC_RTCEN_bm;
irq_attach(AVRDX_IRQ_RTC_CNT, (xcpt_t)avrdx_timerisr, NULL);
up_irq_restore(irqstate);
}

63
arch/avr/src/avrdx/chip.h Normal file
View file

@ -0,0 +1,63 @@
/****************************************************************************
* arch/avr/src/avrdx/chip.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_AVR_SRC_AVRDX_CHIP_H
#define __ARCH_AVR_SRC_AVRDX_CHIP_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/* Define features for supported chip in the AVRnDx family */
#if 1
#else
# error "Unsupported AVR chip"
#endif
/* Include only the memory map.
* Other chip hardware files should then include this file for the proper
* setup
*
*/
#include "avrdx_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Functions Prototypes Prototypes
****************************************************************************/
#endif /* __ARCH_AVR_SRC_AVRDX_CHIP_H */

View file

@ -0,0 +1,96 @@
/****************************************************************************
* arch/avr/src/avrdx/iodefs/avr128da28.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_AVR_SRC_AVRDX_IODEFS_AVR128DA28_H
#define __ARCH_AVR_SRC_AVRDX_IODEFS_AVR128DA28_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <avr/io.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef __ARCH_AVR_SRC_AVRDX_AVRDX_IODEFS_H
# error "Do not include this file directly, use avrdx_iodefs.h instead"
#endif
/* CLKCTRL.OSCHFCTRLA */
#define CLKCTRL_FRQSEL_GM ( CLKCTRL_FRQSEL_0_bm | CLKCTRL_FRQSEL_1_bm | \
CLKCTRL_FRQSEL_2_bm | CLKCTRL_FRQSEL_3_bm )
#define CLKCTRL_FRQSEL_1M_GC (0)
#define CLKCTRL_FRQSEL_2M_GC (CLKCTRL_FRQSEL_0_bm)
#define CLKCTRL_FRQSEL_3M_GC (CLKCTRL_FRQSEL_1_bm)
#define CLKCTRL_FRQSEL_4M_GC (CLKCTRL_FRQSEL_1_bm | CLKCTRL_FRQSEL_0_bm)
#define CLKCTRL_FRQSEL_8M_GC (CLKCTRL_FRQSEL_2_bm | CLKCTRL_FRQSEL_0_bm)
#define CLKCTRL_FRQSEL_12M_GC (CLKCTRL_FRQSEL_2_bm | CLKCTRL_FRQSEL_1_bm)
#define CLKCTRL_FRQSEL_16M_GC (CLKCTRL_FRQSEL_2_bm | CLKCTRL_FRQSEL_1_bm | \
CLKCTRL_FRQSEL_0_bm )
#define CLKCTRL_FRQSEL_20M_GC (CLKCTRL_FRQSEL_3_bm)
#define CLKCTRL_FRQSEL_24M_GC (CLKCTRL_FRQSEL_3_bm | CLKCTRL_FRQSEL_0_bm)
/* RTC.CTRLA */
#define RTC_PRESCALER_GM ( RTC_PRESCALER_0_bm | RTC_PRESCALER_1_bm | \
RTC_PRESCALER_2_bm | RTC_PRESCALER_3_bm )
#define RTC_PRESCALER_DIV2_GC (RTC_PRESCALER_0_bm)
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_AVR_SRC_AVRDX_AVRDX_H */

View file

@ -59,12 +59,17 @@
#define INTSTACK_COLOR 's'
#define HEAP_COLOR 'h'
#define getreg8(a) (*(volatile uint8_t *)(a))
#define putreg8(v,a) (*(volatile uint8_t *)(a) = (v))
#define getreg16(a) (*(volatile uint16_t *)(a))
#define putreg16(v,a) (*(volatile uint16_t *)(a) = (v))
#define getreg32(a) (*(volatile uint32_t *)(a))
#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
/* ATMega and similar chips have their registers memory-mapped,
* Dx cores don't
*/
#ifndef CONFIG_ARCH_CHIP_AVRDX
# define getreg8(a) (*(volatile uint8_t *)(a))
# define putreg8(v,a) (*(volatile uint8_t *)(a) = (v))
# define getreg16(a) (*(volatile uint16_t *)(a))
# define putreg16(v,a) (*(volatile uint16_t *)(a) = (v))
# define getreg32(a) (*(volatile uint32_t *)(a))
# define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
#endif
/****************************************************************************
* Public Types