cpu/avr8_common: Normalize method prefix name
Refactor atmega_ prefix to avr8_ prefix and update copyrights. Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
This commit is contained in:
parent
4cbd311196
commit
1426e15679
@ -35,7 +35,7 @@ void board_init(void)
|
|||||||
PRR1 |= 1<<PRUSB;
|
PRR1 |= 1<<PRUSB;
|
||||||
|
|
||||||
atmega_set_prescaler(CPU_ATMEGA_CLK_SCALE_INIT);
|
atmega_set_prescaler(CPU_ATMEGA_CLK_SCALE_INIT);
|
||||||
atmega_stdio_init();
|
avr8_stdio_init();
|
||||||
cpu_init();
|
cpu_init();
|
||||||
led_init();
|
led_init();
|
||||||
irq_enable();
|
irq_enable();
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
extern uint8_t mcusr_mirror;
|
extern uint8_t mcusr_mirror;
|
||||||
extern uint8_t soft_rst;
|
extern uint8_t soft_rst;
|
||||||
|
|
||||||
void atmega_reset_cause(void)
|
void avr8_reset_cause(void)
|
||||||
{
|
{
|
||||||
if (mcusr_mirror & (1 << PORF)) {
|
if (mcusr_mirror & (1 << PORF)) {
|
||||||
DEBUG("Power-on reset.\n");
|
DEBUG("Power-on reset.\n");
|
||||||
@ -75,7 +75,7 @@ void atmega_reset_cause(void)
|
|||||||
*/
|
*/
|
||||||
ISR(BADISR_vect)
|
ISR(BADISR_vect)
|
||||||
{
|
{
|
||||||
atmega_reset_cause();
|
avr8_reset_cause();
|
||||||
|
|
||||||
#if defined (CPU_ATMEGA256RFR2)
|
#if defined (CPU_ATMEGA256RFR2)
|
||||||
printf("IRQ_STATUS %#02x\nIRQ_STATUS1 %#02x\n",
|
printf("IRQ_STATUS %#02x\nIRQ_STATUS1 %#02x\n",
|
||||||
@ -97,8 +97,8 @@ ISR(BADISR_vect)
|
|||||||
#if defined(CPU_ATMEGA128RFA1) || defined (CPU_ATMEGA256RFR2)
|
#if defined(CPU_ATMEGA128RFA1) || defined (CPU_ATMEGA256RFR2)
|
||||||
ISR(BAT_LOW_vect, ISR_BLOCK)
|
ISR(BAT_LOW_vect, ISR_BLOCK)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
DEBUG("BAT_LOW\n");
|
DEBUG("BAT_LOW\n");
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -371,16 +371,16 @@ void gpio_irq_disable(gpio_t pin)
|
|||||||
|
|
||||||
static inline void irq_handler(uint8_t int_num)
|
static inline void irq_handler(uint8_t int_num)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
config[int_num].cb(config[int_num].arg);
|
config[int_num].cb(config[int_num].arg);
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PCINT
|
#ifdef ENABLE_PCINT
|
||||||
/* inline function that is used by the PCINT ISR */
|
/* inline function that is used by the PCINT ISR */
|
||||||
static inline void pcint_handler(uint8_t bank, uint8_t enabled_pcints)
|
static inline void pcint_handler(uint8_t bank, uint8_t enabled_pcints)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
/* Find right item */
|
/* Find right item */
|
||||||
uint8_t idx = 0;
|
uint8_t idx = 0;
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ static inline void pcint_handler(uint8_t bank, uint8_t enabled_pcints)
|
|||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
#ifdef MODULE_ATMEGA_PCINT0
|
#ifdef MODULE_ATMEGA_PCINT0
|
||||||
ISR(PCINT0_vect, ISR_BLOCK)
|
ISR(PCINT0_vect, ISR_BLOCK)
|
||||||
|
|||||||
@ -34,7 +34,7 @@ static void *alarm_cb_arg;
|
|||||||
/* will be called every second */
|
/* will be called every second */
|
||||||
ISR(TIMER2_OVF_vect)
|
ISR(TIMER2_OVF_vect)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
|
|
||||||
isr_flag = !isr_flag;
|
isr_flag = !isr_flag;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ ISR(TIMER2_OVF_vect)
|
|||||||
alarm_cb(alarm_cb_arg);
|
alarm_cb(alarm_cb_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_init(void)
|
void rtc_init(void)
|
||||||
|
|||||||
@ -447,18 +447,18 @@ void rtt_poweroff(void)
|
|||||||
#if RTT_BACKEND_SC
|
#if RTT_BACKEND_SC
|
||||||
ISR(SCNT_OVFL_vect)
|
ISR(SCNT_OVFL_vect)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
/* Execute callback */
|
/* Execute callback */
|
||||||
if (rtt_state.overflow_cb != NULL) {
|
if (rtt_state.overflow_cb != NULL) {
|
||||||
rtt_state.overflow_cb(rtt_state.overflow_arg);
|
rtt_state.overflow_cb(rtt_state.overflow_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
ISR(TIMER2_OVF_vect)
|
ISR(TIMER2_OVF_vect)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
|
|
||||||
ext_cnt++;
|
ext_cnt++;
|
||||||
|
|
||||||
@ -479,7 +479,7 @@ ISR(TIMER2_OVF_vect)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -489,7 +489,7 @@ ISR(SCNT_CMP2_vect)
|
|||||||
ISR(TIMER2_COMPA_vect)
|
ISR(TIMER2_COMPA_vect)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
/* Disable alarm interrupt */
|
/* Disable alarm interrupt */
|
||||||
#if RTT_BACKEND_SC
|
#if RTT_BACKEND_SC
|
||||||
SCIRQM &= ~(1 << IRQMCP2);
|
SCIRQM &= ~(1 << IRQMCP2);
|
||||||
@ -505,5 +505,5 @@ ISR(TIMER2_COMPA_vect)
|
|||||||
cb(rtt_state.alarm_arg);
|
cb(rtt_state.alarm_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -277,7 +277,7 @@ static inline void _isr(tim_t tim, int chan)
|
|||||||
DEBUG_TIMER_PORT |= (1 << DEBUG_TIMER_PIN);
|
DEBUG_TIMER_PORT |= (1 << DEBUG_TIMER_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
|
|
||||||
if (is_oneshot(tim, chan)) {
|
if (is_oneshot(tim, chan)) {
|
||||||
*ctx[tim].mask &= ~(1 << (chan + OCIE1A));
|
*ctx[tim].mask &= ~(1 << (chan + OCIE1A));
|
||||||
@ -288,7 +288,7 @@ static inline void _isr(tim_t tim, int chan)
|
|||||||
DEBUG_TIMER_PORT &= ~(1 << DEBUG_TIMER_PIN);
|
DEBUG_TIMER_PORT &= ~(1 << DEBUG_TIMER_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -122,7 +122,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t count = UINT16_MAX;
|
uint16_t count = UINT16_MAX;
|
||||||
while (atmega_is_uart_tx_pending() && count--) {}
|
while (avr8_is_uart_tx_pending() && count--) {}
|
||||||
|
|
||||||
/* register interrupt context */
|
/* register interrupt context */
|
||||||
isr_ctx[uart].rx_cb = rx_cb;
|
isr_ctx[uart].rx_cb = rx_cb;
|
||||||
@ -174,7 +174,7 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
|||||||
/* start of TX won't finish until no data in UDRn and transmit shift
|
/* start of TX won't finish until no data in UDRn and transmit shift
|
||||||
register is empty */
|
register is empty */
|
||||||
unsigned long state = irq_disable();
|
unsigned long state = irq_disable();
|
||||||
atmega_state |= ATMEGA_STATE_FLAG_UART_TX(uart);
|
avr8_state |= AVR8_STATE_FLAG_UART_TX(uart);
|
||||||
irq_restore(state);
|
irq_restore(state);
|
||||||
dev[uart]->DR = data[i];
|
dev[uart]->DR = data[i];
|
||||||
}
|
}
|
||||||
@ -194,22 +194,22 @@ void uart_poweroff(uart_t uart)
|
|||||||
|
|
||||||
static inline void _rx_isr_handler(int num)
|
static inline void _rx_isr_handler(int num)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
|
|
||||||
isr_ctx[num].rx_cb(isr_ctx[num].arg, dev[num]->DR);
|
isr_ctx[num].rx_cb(isr_ctx[num].arg, dev[num]->DR);
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _tx_isr_handler(int num)
|
static inline void _tx_isr_handler(int num)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
|
|
||||||
/* entire frame in the Transmit Shift Register has been shifted out and
|
/* entire frame in the Transmit Shift Register has been shifted out and
|
||||||
there are no new data currently present in the transmit buffer */
|
there are no new data currently present in the transmit buffer */
|
||||||
atmega_state &= ~ATMEGA_STATE_FLAG_UART_TX(num);
|
avr8_state &= ~AVR8_STATE_FLAG_UART_TX(num);
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||||
* 2017 RWTH Aachen, Josua Arndt
|
* 2017 RWTH Aachen, Josua Arndt
|
||||||
* 2018 Matthew Blue
|
* 2018 Matthew Blue
|
||||||
|
* 2021 Gerson Fernando Budke
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -9,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup cpu_atmega_common
|
* @ingroup cpu_avr8_common
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
@ -20,7 +21,8 @@
|
|||||||
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
||||||
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
||||||
* @author Francisco Acosta <francisco.acosta@inria.fr>
|
* @author Francisco Acosta <francisco.acosta@inria.fr>
|
||||||
|
* @author Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
|
*
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -58,7 +60,8 @@
|
|||||||
*/
|
*/
|
||||||
uint8_t mcusr_mirror __attribute__((section(".noinit")));
|
uint8_t mcusr_mirror __attribute__((section(".noinit")));
|
||||||
uint8_t soft_rst __attribute__((section(".noinit")));
|
uint8_t soft_rst __attribute__((section(".noinit")));
|
||||||
uint8_t atmega_state = 0;
|
uint8_t avr8_state = 0;
|
||||||
|
|
||||||
void get_mcusr(void) __attribute__((naked, section(".init0"), used));
|
void get_mcusr(void) __attribute__((naked, section(".init0"), used));
|
||||||
|
|
||||||
void get_mcusr(void)
|
void get_mcusr(void)
|
||||||
@ -78,14 +81,14 @@ void get_mcusr(void)
|
|||||||
|
|
||||||
void cpu_init(void)
|
void cpu_init(void)
|
||||||
{
|
{
|
||||||
atmega_reset_cause();
|
avr8_reset_cause();
|
||||||
|
|
||||||
wdt_reset(); /* should not be nececessary as done in bootloader */
|
wdt_reset(); /* should not be nececessary as done in bootloader */
|
||||||
wdt_disable(); /* but when used without bootloader this is needed */
|
wdt_disable(); /* but when used without bootloader this is needed */
|
||||||
|
|
||||||
/* Initialize stdio before periph_init() to allow use of DEBUG() there */
|
/* Initialize stdio before periph_init() to allow use of DEBUG() there */
|
||||||
#ifdef MODULE_AVR_LIBC_EXTRA
|
#ifdef MODULE_AVR_LIBC_EXTRA
|
||||||
atmega_stdio_init();
|
avr8_stdio_init();
|
||||||
#endif
|
#endif
|
||||||
/* Initialize peripherals for which modules are included in the makefile.*/
|
/* Initialize peripherals for which modules are included in the makefile.*/
|
||||||
/* spi_init */
|
/* spi_init */
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Kaspar Schleiser <kaspar@schleiser.de>
|
* Copyright (C) 2018 Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
* 2021 Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -10,9 +11,10 @@
|
|||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
* @brief Implements common atmega libc stdio initialization
|
* @brief Implements common avr8 libc stdio initialization
|
||||||
*
|
*
|
||||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
* @author Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
*
|
*
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
@ -41,7 +43,7 @@ static int _uart_getchar(FILE *stream)
|
|||||||
return (int)c;
|
return (int)c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void atmega_stdio_init(void)
|
void avr8_stdio_init(void)
|
||||||
{
|
{
|
||||||
stdio_init();
|
stdio_init();
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg
|
* Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg
|
||||||
|
* 2021 Gerson Fernando Budke
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -7,13 +8,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup cpu_atmega_common
|
* @ingroup cpu_avr8_common
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
* @brief Architecture details
|
* @brief Architecture details
|
||||||
*
|
*
|
||||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||||
|
* @author Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg
|
* Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg
|
||||||
|
* 2021 Gerson Fernando Budke
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
* 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
|
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||||
@ -7,13 +8,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup cpu_atmega_common
|
* @ingroup cpu_avr8_common
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
* @brief Implementation of fast atomic utility functions
|
* @brief Implementation of fast atomic utility functions
|
||||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||||
|
* @author Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ATOMIC_UTILS_ARCH_H
|
#ifndef ATOMIC_UTILS_ARCH_H
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
|
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
* 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
* 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||||
* 2018 RWTH Aachen, Josua Arndt <jarndt@ias.rwth-aachen.de>
|
* 2018 RWTH Aachen, Josua Arndt <jarndt@ias.rwth-aachen.de>
|
||||||
|
* 2021 Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -9,12 +10,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup cpu_atmega_common
|
* @ingroup cpu_avr8_common
|
||||||
* @brief Common implementations and headers for ATmega family based micro-controllers
|
* @brief Common implementations and headers for AVR-8 family based micro-controllers
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
* @brief Basic definitions for the ATmega common module
|
* @brief Basic definitions for the AVR-8 common module
|
||||||
*
|
*
|
||||||
* When ever you want to do something hardware related, that is accessing MCUs registers directly,
|
* When ever you want to do something hardware related, that is accessing MCUs registers directly,
|
||||||
* just include this file. It will then make sure that the MCU specific headers are included.
|
* just include this file. It will then make sure that the MCU specific headers are included.
|
||||||
@ -24,6 +25,7 @@
|
|||||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
||||||
|
* @author Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -58,10 +60,10 @@ extern "C"
|
|||||||
* @name Flags for the current state of the ATmega MCU
|
* @name Flags for the current state of the ATmega MCU
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define ATMEGA_STATE_FLAG_ISR (0x80U) /**< In ISR */
|
#define AVR8_STATE_FLAG_ISR (0x80U) /**< In ISR */
|
||||||
#define ATMEGA_STATE_FLAG_UART0_TX (0x01U) /**< TX pending for UART 0 */
|
#define AVR8_STATE_FLAG_UART0_TX (0x01U) /**< TX pending for UART 0 */
|
||||||
#define ATMEGA_STATE_FLAG_UART1_TX (0x02U) /**< TX pending for UART 1 */
|
#define AVR8_STATE_FLAG_UART1_TX (0x02U) /**< TX pending for UART 1 */
|
||||||
#define ATMEGA_STATE_FLAG_UART_TX(x) (0x01U << x) /**< TX pending for UART x */
|
#define AVR8_STATE_FLAG_UART_TX(x) (0x01U << x) /**< TX pending for UART x */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,7 +71,7 @@ extern "C"
|
|||||||
*
|
*
|
||||||
* @note This variable is updated from IRQ context; access to it should
|
* @note This variable is updated from IRQ context; access to it should
|
||||||
* be wrapped into @ref irq_disable and @ref irq_restore or
|
* be wrapped into @ref irq_disable and @ref irq_restore or
|
||||||
* @ref atmega_get_state should be used.
|
* @ref avr8_get_state should be used.
|
||||||
*
|
*
|
||||||
* Contents:
|
* Contents:
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -86,26 +88,26 @@ extern "C"
|
|||||||
* | TX1 | This bit is set when on UART1 TX is pending |
|
* | TX1 | This bit is set when on UART1 TX is pending |
|
||||||
* | TX0 | This bit is set when on UART0 TX is pending |
|
* | TX0 | This bit is set when on UART0 TX is pending |
|
||||||
*/
|
*/
|
||||||
extern uint8_t atmega_state;
|
extern uint8_t avr8_state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Atomically read the state (@ref atmega_state)
|
* @brief Atomically read the state (@ref avr8_state)
|
||||||
*
|
*
|
||||||
* This function guarantees that the read is not optimized out, not reordered
|
* This function guarantees that the read is not optimized out, not reordered
|
||||||
* and done atomically. This does not mean that by the time return value is
|
* and done atomically. This does not mean that by the time return value is
|
||||||
* processed that it still reflects the value currently stored in
|
* processed that it still reflects the value currently stored in
|
||||||
* @ref atmega_state.
|
* @ref avr8_state.
|
||||||
*
|
*
|
||||||
* Using ASM rather than C11 atomics has less overhead, as not every access to
|
* Using ASM rather than C11 atomics has less overhead, as not every access to
|
||||||
* the state has to be performed atomically: Those done from ISR will not be
|
* the state has to be performed atomically: Those done from ISR will not be
|
||||||
* interrupted (no support for nested interrupts) and barriers at the begin and
|
* interrupted (no support for nested interrupts) and barriers at the begin and
|
||||||
* end of the ISRs make sure the access takes place before IRQ context is left.
|
* end of the ISRs make sure the access takes place before IRQ context is left.
|
||||||
*/
|
*/
|
||||||
static inline uint8_t atmega_get_state(void)
|
static inline uint8_t avr8_get_state(void)
|
||||||
{
|
{
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
__asm__ volatile(
|
__asm__ volatile(
|
||||||
"lds %[state], atmega_state \n\t"
|
"lds %[state], avr8_state \n\t"
|
||||||
: [state] "=r" (state)
|
: [state] "=r" (state)
|
||||||
:
|
:
|
||||||
: "memory"
|
: "memory"
|
||||||
@ -118,13 +120,13 @@ static inline uint8_t atmega_get_state(void)
|
|||||||
/**
|
/**
|
||||||
* @brief Run this code on entering interrupt routines
|
* @brief Run this code on entering interrupt routines
|
||||||
*/
|
*/
|
||||||
static inline void atmega_enter_isr(void)
|
static inline void avr8_enter_isr(void)
|
||||||
{
|
{
|
||||||
/* This flag is only called from IRQ context, and nested IRQs are not
|
/* This flag is only called from IRQ context, and nested IRQs are not
|
||||||
* supported as of now. The flag will be unset before the IRQ context is
|
* supported as of now. The flag will be unset before the IRQ context is
|
||||||
* left, so no need to use memory barriers or atomics here
|
* left, so no need to use memory barriers or atomics here
|
||||||
*/
|
*/
|
||||||
atmega_state |= ATMEGA_STATE_FLAG_ISR;
|
avr8_state |= AVR8_STATE_FLAG_ISR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,16 +135,16 @@ static inline void atmega_enter_isr(void)
|
|||||||
* @retval !=0 At least on UART device is still sending data out
|
* @retval !=0 At least on UART device is still sending data out
|
||||||
* @retval 0 No UART is currently sending data
|
* @retval 0 No UART is currently sending data
|
||||||
*/
|
*/
|
||||||
static inline int atmega_is_uart_tx_pending(void)
|
static inline int avr8_is_uart_tx_pending(void)
|
||||||
{
|
{
|
||||||
uint8_t state = atmega_get_state();
|
uint8_t state = avr8_get_state();
|
||||||
return (state & (ATMEGA_STATE_FLAG_UART0_TX | ATMEGA_STATE_FLAG_UART1_TX));
|
return (state & (AVR8_STATE_FLAG_UART0_TX | AVR8_STATE_FLAG_UART1_TX));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Run this code on exiting interrupt routines
|
* @brief Run this code on exiting interrupt routines
|
||||||
*/
|
*/
|
||||||
void atmega_exit_isr(void);
|
void avr8_exit_isr(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialization of the CPU
|
* @brief Initialization of the CPU
|
||||||
@ -172,12 +174,12 @@ static inline void __attribute__((always_inline)) cpu_print_last_instruction(voi
|
|||||||
/**
|
/**
|
||||||
* @brief Initializes avrlibc stdio
|
* @brief Initializes avrlibc stdio
|
||||||
*/
|
*/
|
||||||
void atmega_stdio_init(void);
|
void avr8_stdio_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print reset cause
|
* @brief Print reset cause
|
||||||
*/
|
*/
|
||||||
void atmega_reset_cause(void);
|
void avr8_reset_cause(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||||
* 2018 RWTH Aachen, Josua Arndt <jarndt@ias.rwth-aachen.de>
|
* 2018 RWTH Aachen, Josua Arndt <jarndt@ias.rwth-aachen.de>
|
||||||
* 2020 Otto-von-Guericke-Universität Magdeburg
|
* 2020 Otto-von-Guericke-Universität Magdeburg
|
||||||
|
* 2021 Gerson Fernando Budke
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -9,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup cpu_atmega_common
|
* @ingroup cpu_avr8_common
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
@ -19,6 +20,7 @@
|
|||||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||||
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
||||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||||
|
* @author Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -28,7 +30,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "irq.h"
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -98,8 +99,8 @@ __attribute__((always_inline)) static inline void irq_restore(unsigned int _stat
|
|||||||
*/
|
*/
|
||||||
__attribute__((always_inline)) static inline int irq_is_in(void)
|
__attribute__((always_inline)) static inline int irq_is_in(void)
|
||||||
{
|
{
|
||||||
uint8_t state = atmega_get_state();
|
uint8_t state = avr8_get_state();
|
||||||
return (state & ATMEGA_STATE_FLAG_ISR);
|
return (state & AVR8_STATE_FLAG_ISR);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||||
|
* 2021 Gerson Fernando Budke
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -7,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup cpu_atmega_common
|
* @ingroup cpu_avr8_common
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
@ -16,6 +17,7 @@
|
|||||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||||
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
||||||
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
|
* @author Steffen Robertz <steffen.robertz@rwth-aachen.de>
|
||||||
|
* @author Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||||
* 2017 Thomas Perrot <thomas.perrot@tupi.fr>
|
* 2017 Thomas Perrot <thomas.perrot@tupi.fr>
|
||||||
* 2018 RWTH Aachen, Josua Arndt <jarndt@ias.rwth-aachen.de>
|
* 2018 RWTH Aachen, Josua Arndt <jarndt@ias.rwth-aachen.de>
|
||||||
|
* 2021 Gerson Fernando Budke
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -9,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup cpu_atmega_common
|
* @ingroup cpu_avr8_common
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
@ -18,6 +19,7 @@
|
|||||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||||
* @author Thomas Perrot <thomas.perrot@tupi.fr>
|
* @author Thomas Perrot <thomas.perrot@tupi.fr>
|
||||||
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
|
||||||
|
* @author Gerson Fernando Budke <nandojve@gmail.com>
|
||||||
*
|
*
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
@ -30,13 +32,13 @@
|
|||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
|
||||||
static void atmega_context_save(void);
|
static void avr8_context_save(void);
|
||||||
static void atmega_context_restore(void);
|
static void avr8_context_restore(void);
|
||||||
static void atmega_enter_thread_mode(void);
|
static void avr8_enter_thread_mode(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Since AVR doesn't support direct manipulation of the program counter we
|
* @brief Since AVR doesn't support direct manipulation of the program counter we
|
||||||
* model a stack like it would be left by atmega_context_save().
|
* model a stack like it would be left by avr8_context_save().
|
||||||
* The resulting layout in memory is the following:
|
* The resulting layout in memory is the following:
|
||||||
* ---------------thread_t (not created by thread_stack_init) ----------
|
* ---------------thread_t (not created by thread_stack_init) ----------
|
||||||
* local variables (a temporary value and the stackpointer)
|
* local variables (a temporary value and the stackpointer)
|
||||||
@ -48,7 +50,7 @@ static void atmega_enter_thread_mode(void);
|
|||||||
* -----------------------------------------------------------------------
|
* -----------------------------------------------------------------------
|
||||||
* a 16 Bit pointer to task_func
|
* a 16 Bit pointer to task_func
|
||||||
* this is placed exactly at the place where the program counter would be
|
* this is placed exactly at the place where the program counter would be
|
||||||
* stored normally and thus can be returned to when atmega_context_restore()
|
* stored normally and thus can be returned to when avr8_context_restore()
|
||||||
* has been run
|
* has been run
|
||||||
* (Optional 17 bit (bit is set to zero) for devices with > 128kb FLASH)
|
* (Optional 17 bit (bit is set to zero) for devices with > 128kb FLASH)
|
||||||
* -----------------------------------------------------------------------
|
* -----------------------------------------------------------------------
|
||||||
@ -61,7 +63,7 @@ static void atmega_enter_thread_mode(void);
|
|||||||
* r26 - r31
|
* r26 - r31
|
||||||
* -----------------------------------------------------------------------
|
* -----------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* After the invocation of atmega_context_restore() the pointer to task_func is
|
* After the invocation of avr8_context_restore() the pointer to task_func is
|
||||||
* on top of the stack and can be returned to. This way we can actually place
|
* on top of the stack and can be returned to. This way we can actually place
|
||||||
* it inside of the program counter of the MCU.
|
* it inside of the program counter of the MCU.
|
||||||
* if task_func returns sched_task_exit gets popped into the PC
|
* if task_func returns sched_task_exit gets popped into the PC
|
||||||
@ -198,7 +200,7 @@ void thread_stack_print(void)
|
|||||||
void cpu_switch_context_exit(void)
|
void cpu_switch_context_exit(void)
|
||||||
{
|
{
|
||||||
sched_run();
|
sched_run();
|
||||||
atmega_enter_thread_mode();
|
avr8_enter_thread_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STACK_POINTER ((char *)AVR_STACK_POINTER_REG)
|
#define STACK_POINTER ((char *)AVR_STACK_POINTER_REG)
|
||||||
@ -210,7 +212,7 @@ extern char *__brkval;
|
|||||||
/**
|
/**
|
||||||
* @brief Set the MCU into Thread-Mode and load the initial task from the stack and run it
|
* @brief Set the MCU into Thread-Mode and load the initial task from the stack and run it
|
||||||
*/
|
*/
|
||||||
void NORETURN atmega_enter_thread_mode(void)
|
void NORETURN avr8_enter_thread_mode(void)
|
||||||
{
|
{
|
||||||
irq_enable();
|
irq_enable();
|
||||||
|
|
||||||
@ -226,7 +228,7 @@ void NORETURN atmega_enter_thread_mode(void)
|
|||||||
__brkval = __malloc_heap_start;
|
__brkval = __malloc_heap_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
atmega_context_restore();
|
avr8_context_restore();
|
||||||
__asm__ volatile ("ret");
|
__asm__ volatile ("ret");
|
||||||
|
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -235,9 +237,9 @@ void NORETURN atmega_enter_thread_mode(void)
|
|||||||
void thread_yield_higher(void)
|
void thread_yield_higher(void)
|
||||||
{
|
{
|
||||||
if (irq_is_in() == 0) {
|
if (irq_is_in() == 0) {
|
||||||
atmega_context_save();
|
avr8_context_save();
|
||||||
sched_run();
|
sched_run();
|
||||||
atmega_context_restore();
|
avr8_context_restore();
|
||||||
__asm__ volatile ("ret");
|
__asm__ volatile ("ret");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -245,20 +247,20 @@ void thread_yield_higher(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void atmega_exit_isr(void)
|
void avr8_exit_isr(void)
|
||||||
{
|
{
|
||||||
atmega_state &= ~ATMEGA_STATE_FLAG_ISR;
|
avr8_state &= ~AVR8_STATE_FLAG_ISR;
|
||||||
/* Force access to atmega_state to take place */
|
/* Force access to avr8_state to take place */
|
||||||
__asm__ volatile ("" : : : "memory");
|
__asm__ volatile ("" : : : "memory");
|
||||||
if (sched_context_switch_request) {
|
if (sched_context_switch_request) {
|
||||||
atmega_context_save();
|
avr8_context_save();
|
||||||
sched_run();
|
sched_run();
|
||||||
atmega_context_restore();
|
avr8_context_restore();
|
||||||
__asm__ volatile ("reti");
|
__asm__ volatile ("reti");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline void atmega_context_save(void)
|
__attribute__((always_inline)) static inline void avr8_context_save(void)
|
||||||
{
|
{
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"push __tmp_reg__ \n\t"
|
"push __tmp_reg__ \n\t"
|
||||||
@ -313,7 +315,7 @@ __attribute__((always_inline)) static inline void atmega_context_save(void)
|
|||||||
"st x+, __tmp_reg__ \n\t");
|
"st x+, __tmp_reg__ \n\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline)) static inline void atmega_context_restore(void)
|
__attribute__((always_inline)) static inline void avr8_context_restore(void)
|
||||||
{
|
{
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"lds r26, sched_active_thread \n\t"
|
"lds r26, sched_active_thread \n\t"
|
||||||
|
|||||||
@ -870,7 +870,7 @@ ISR(TRX24_TX_START_vect){
|
|||||||
*/
|
*/
|
||||||
ISR(TRX24_RX_END_vect, ISR_BLOCK)
|
ISR(TRX24_RX_END_vect, ISR_BLOCK)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
|
|
||||||
uint8_t status = *AT86RF2XX_REG__TRX_STATE & AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
|
uint8_t status = *AT86RF2XX_REG__TRX_STATE & AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
|
||||||
DEBUG("TRX24_RX_END 0x%x\n", status);
|
DEBUG("TRX24_RX_END 0x%x\n", status);
|
||||||
@ -879,7 +879,7 @@ ISR(TRX24_RX_END_vect, ISR_BLOCK)
|
|||||||
/* Call upper layer to process received data */
|
/* Call upper layer to process received data */
|
||||||
netdev_trigger_event_isr(at86rfmega_dev);
|
netdev_trigger_event_isr(at86rfmega_dev);
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -892,12 +892,12 @@ ISR(TRX24_RX_END_vect, ISR_BLOCK)
|
|||||||
*/
|
*/
|
||||||
ISR(TRX24_XAH_AMI_vect, ISR_BLOCK)
|
ISR(TRX24_XAH_AMI_vect, ISR_BLOCK)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
|
|
||||||
DEBUG("TRX24_XAH_AMI\n");
|
DEBUG("TRX24_XAH_AMI\n");
|
||||||
((at86rf2xx_t *)at86rfmega_dev)->irq_status |= AT86RF2XX_IRQ_STATUS_MASK__AMI;
|
((at86rf2xx_t *)at86rfmega_dev)->irq_status |= AT86RF2XX_IRQ_STATUS_MASK__AMI;
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -909,7 +909,7 @@ ISR(TRX24_XAH_AMI_vect, ISR_BLOCK)
|
|||||||
*/
|
*/
|
||||||
ISR(TRX24_TX_END_vect, ISR_BLOCK)
|
ISR(TRX24_TX_END_vect, ISR_BLOCK)
|
||||||
{
|
{
|
||||||
atmega_enter_isr();
|
avr8_enter_isr();
|
||||||
|
|
||||||
at86rf2xx_t *dev = (at86rf2xx_t *) at86rfmega_dev;
|
at86rf2xx_t *dev = (at86rf2xx_t *) at86rfmega_dev;
|
||||||
uint8_t status = *AT86RF2XX_REG__TRX_STATE & AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
|
uint8_t status = *AT86RF2XX_REG__TRX_STATE & AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
|
||||||
@ -924,7 +924,7 @@ ISR(TRX24_TX_END_vect, ISR_BLOCK)
|
|||||||
netdev_trigger_event_isr(at86rfmega_dev);
|
netdev_trigger_event_isr(at86rfmega_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
atmega_exit_isr();
|
avr8_exit_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MODULE_AT86RFA1 || MODULE_AT86RFR2 */
|
#endif /* MODULE_AT86RFA1 || MODULE_AT86RFR2 */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user