mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu: atmega_common: Initial import
This commit is contained in:
parent
1c25af18e2
commit
a6b77b4745
5
cpu/atmega_common/Makefile
Normal file
5
cpu/atmega_common/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
# define the module that is build
|
||||
MODULE = atmega_common
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
3
cpu/atmega_common/Makefile.include
Normal file
3
cpu/atmega_common/Makefile.include
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
# include module specific includes
|
||||
export INCLUDES += -I$(RIOTCPU)/atmega_common/include -isystem$(RIOTCPU)/atmega_common/avr-libc-extra
|
33
cpu/atmega_common/atomic_arch.c
Normal file
33
cpu/atmega_common/atomic_arch.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_atmega_common
|
||||
* @{
|
||||
*
|
||||
* @file atomic_arch.c
|
||||
* @brief Implementation of the kernels atomic interface
|
||||
*
|
||||
* @author Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/atomic_arch.h"
|
||||
#include "irq.h"
|
||||
|
||||
unsigned int atomic_arch_set_return(unsigned int *to_set, unsigned int value)
|
||||
{
|
||||
disableIRQ();
|
||||
unsigned int old = *to_set;
|
||||
*to_set = value;
|
||||
enableIRQ();
|
||||
return old;
|
||||
}
|
147
cpu/atmega_common/avr-libc-extra/errno.h
Normal file
147
cpu/atmega_common/avr-libc-extra/errno.h
Normal file
@ -0,0 +1,147 @@
|
||||
/* Copyright (c) 2002,2007 Marek Michalkiewicz
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __ERRNO_H_
|
||||
#define __ERRNO_H_ 1
|
||||
|
||||
/** \file */
|
||||
/** \defgroup avr_errno <errno.h>: System Errors
|
||||
|
||||
\code #include <errno.h>\endcode
|
||||
|
||||
Some functions in the library set the global variable \c errno when an
|
||||
error occurs. The file, \c <errno.h>, provides symbolic names for various
|
||||
error codes.
|
||||
|
||||
\warning The \c errno global variable is not safe to use in a threaded or
|
||||
multi-task system. A race condition can occur if a task is interrupted
|
||||
between the call which sets \c error and when the task examines \c
|
||||
errno. If another task changes \c errno during this time, the result will
|
||||
be incorrect for the interrupted task. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int errno;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \ingroup avr_errno
|
||||
\def EDOM
|
||||
|
||||
Domain error. */
|
||||
#define EDOM 33
|
||||
|
||||
/** \ingroup avr_errno
|
||||
\def ERANGE
|
||||
|
||||
Range error. */
|
||||
#define ERANGE 34
|
||||
|
||||
/* ((((('E'-64)*26+('N'-64))*26+('O'-64))*26+('S'-64))*26+('Y'-64))*26+'S'-64 */
|
||||
#define ENOSYS ((int)(66081697 & 0x7fff))
|
||||
|
||||
/* (((('E'-64)*26+('I'-64))*26+('N'-64))*26+('T'-64))*26+('R'-64) */
|
||||
#define EINTR ((int)(2453066 & 0x7fff))
|
||||
|
||||
#define E2BIG ENOERR
|
||||
#define EACCES ENOERR
|
||||
#define EADDRINUSE ENOERR
|
||||
#define EADDRNOTAVAIL ENOERR
|
||||
#define EAFNOSUPPORT ENOERR
|
||||
#define EAGAIN ENOERR
|
||||
#define EALREADY ENOERR
|
||||
#define EBADF ENOERR
|
||||
//#define EBUSY ENOERR
|
||||
#define ECHILD ENOERR
|
||||
#define ECONNABORTED ENOERR
|
||||
#define ECONNREFUSED ENOERR
|
||||
#define ECONNRESET ENOERR
|
||||
#define EDEADLK ENOERR
|
||||
#define EDESTADDRREQ ENOERR
|
||||
#define EEXIST ENOERR
|
||||
#define EFAULT ENOERR
|
||||
#define EFBIG ENOERR
|
||||
#define EHOSTUNREACH ENOERR
|
||||
#define EILSEQ ENOERR
|
||||
#define EINPROGRESS ENOERR
|
||||
//#define EINVAL ENOERR
|
||||
#define EIO ENOERR
|
||||
#define EISCONN ENOERR
|
||||
#define EISDIR ENOERR
|
||||
#define ELOOP ENOERR
|
||||
#define EMFILE ENOERR
|
||||
#define EMLINK ENOERR
|
||||
#define EMSGSIZE ENOERR
|
||||
#define ENAMETOOLONG ENOERR
|
||||
#define ENETDOWN ENOERR
|
||||
#define ENETRESET ENOERR
|
||||
#define ENETUNREACH ENOERR
|
||||
#define ENFILE ENOERR
|
||||
#define ENOBUFS ENOERR
|
||||
#define ENODEV ENOERR
|
||||
#define ENOENT ENOERR
|
||||
#define ENOEXEC ENOERR
|
||||
#define ENOLCK ENOERR
|
||||
#define ENOMEM ENOERR
|
||||
#define ENOMSG ENOERR
|
||||
#define ENOPROTOOPT ENOERR
|
||||
#define ENOSPC ENOERR
|
||||
#define ENOTCONN ENOERR
|
||||
#define ENOTDIR ENOERR
|
||||
#define ENOTEMPTY ENOERR
|
||||
#define ENOTSOCK ENOERR
|
||||
#define ENOTTY ENOERR
|
||||
#define ENXIO ENOERR
|
||||
#define EOPNOTSUPP ENOERR
|
||||
#define EPERM ENOERR
|
||||
#define EPIPE ENOERR
|
||||
#define EPROTONOSUPPORT ENOERR
|
||||
#define EPROTOTYPE ENOERR
|
||||
#define EROFS ENOERR
|
||||
#define ESPIPE ENOERR
|
||||
#define ESRCH ENOERR
|
||||
#define ETIMEDOUT ENOERR
|
||||
#define EWOULDBLOCK ENOERR
|
||||
#define EXDEV ENOERR
|
||||
|
||||
/* ((((('E'-64)*26+('N'-64))*26+('O'-64))*26+('E'-64))*26+('R'-64))*26+'R'-64 */
|
||||
#define ENOERR ((int)(66072050 & 0xffff))
|
||||
|
||||
#define EBUSY 16 /* Device or resource busy */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define EOVERFLOW 75 /* Value too large for defined data type */
|
||||
|
||||
#endif
|
528
cpu/atmega_common/avr-libc-extra/time.h
Normal file
528
cpu/atmega_common/avr-libc-extra/time.h
Normal file
@ -0,0 +1,528 @@
|
||||
/*
|
||||
* (C)2012 Michael Duane Rice All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer. Redistributions in binary
|
||||
* form must reproduce the above copyright notice, this list of conditions
|
||||
* and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution. Neither the name of the copyright holders
|
||||
* nor the names of contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/** \file */
|
||||
|
||||
/** \defgroup avr_time <time.h>: Time
|
||||
\code #include <time.h> \endcode
|
||||
<h3>Introduction to the Time functions</h3>
|
||||
This file declares the time functions implemented in \c avr-libc.
|
||||
|
||||
The implementation aspires to conform with ISO/IEC 9899 (C90). However, due to limitations of the
|
||||
target processor and the nature of its development environment, a practical implementation must
|
||||
of necessity deviate from the standard.
|
||||
|
||||
|
||||
|
||||
Section 7.23.2.1 clock()
|
||||
The type clock_t, the macro CLOCKS_PER_SEC, and the function clock() are not implemented. We
|
||||
consider these items belong to operating system code, or to application code when no operating
|
||||
system is present.
|
||||
|
||||
Section 7.23.2.3 mktime()
|
||||
The standard specifies that mktime() should return (time_t) -1, if the time cannot be represented.
|
||||
This implementation always returns a 'best effort' representation.
|
||||
|
||||
Section 7.23.2.4 time()
|
||||
The standard specifies that time() should return (time_t) -1, if the time is not available.
|
||||
Since the application must initialize the time system, this functionality is not implemented.
|
||||
|
||||
Section 7.23.2.2, difftime()
|
||||
Due to the lack of a 64 bit double, the function difftime() returns a long integer. In most cases
|
||||
this change will be invisible to the user, handled automatically by the compiler.
|
||||
|
||||
Section 7.23.1.4 struct tm
|
||||
Per the standard, struct tm->tm_isdst is greater than zero when Daylight Saving time is in effect.
|
||||
This implementation further specifies that, when positive, the value of tm_isdst represents
|
||||
the amount time is advanced during Daylight Saving time.
|
||||
|
||||
Section 7.23.3.5 strftime()
|
||||
Only the 'C' locale is supported, therefore the modifiers 'E' and 'O' are ignored.
|
||||
The 'Z' conversion is also ignored, due to the lack of time zone name.
|
||||
|
||||
In addition to the above departures from the standard, there are some behaviors which are different
|
||||
from what is often expected, though allowed under the standard.
|
||||
|
||||
There is no 'platform standard' method to obtain the current time, time zone, or
|
||||
daylight savings 'rules' in the AVR environment. Therefore the application must initialize
|
||||
the time system with this information. The functions set_zone(), set_dst(), and
|
||||
set_system_time() are provided for initialization. Once initialized, system time is maintained by
|
||||
calling the function system_tick() at one second intervals.
|
||||
|
||||
Though not specified in the standard, it is often expected that time_t is a signed integer
|
||||
representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. This implementation
|
||||
uses an unsigned 32 bit integer offset from Midnight Jan 1 2000. The use of this 'epoch' helps to
|
||||
simplify the conversion functions, while the 32 bit value allows time to be properly represented
|
||||
until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in
|
||||
converting to and from Unix and NTP time stamps.
|
||||
|
||||
Unlike desktop counterparts, it is impractical to implement or maintain the 'zoneinfo' database.
|
||||
Therefore no attempt is made to account for time zone, daylight saving, or leap seconds in past dates.
|
||||
All calculations are made according to the currently configured time zone and daylight saving 'rule'.
|
||||
|
||||
In addition to C standard functions, re-entrant versions of ctime(), asctime(), gmtime() and
|
||||
localtime() are provided which, in addition to being re-entrant, have the property of claiming
|
||||
less permanent storage in RAM. An additional time conversion, isotime() and its re-entrant version,
|
||||
uses far less storage than either ctime() or asctime().
|
||||
|
||||
Along with the usual smattering of utility functions, such as is_leap_year(), this library includes
|
||||
a set of functions related the sun and moon, as well as sidereal time functions.
|
||||
*/
|
||||
|
||||
#ifndef TIME_H
|
||||
#define TIME_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** \ingroup avr_time */
|
||||
/* @{ */
|
||||
|
||||
/**
|
||||
time_t represents seconds elapsed from Midnight, Jan 1 2000 UTC (the Y2K 'epoch').
|
||||
Its range allows this implementation to represent time up to Tue Feb 7 06:28:15 2136 UTC.
|
||||
*/
|
||||
typedef uint32_t time_t;
|
||||
|
||||
/**
|
||||
The time function returns the systems current time stamp.
|
||||
If timer is not a null pointer, the return value is also assigned to the object it points to.
|
||||
*/
|
||||
time_t time(time_t *timer);
|
||||
|
||||
/**
|
||||
The difftime function returns the difference between two binary time stamps,
|
||||
time1 - time0.
|
||||
*/
|
||||
int32_t difftime(time_t time1, time_t time0);
|
||||
|
||||
|
||||
/**
|
||||
The tm structure contains a representation of time 'broken down' into components of the
|
||||
Gregorian calendar.
|
||||
|
||||
The normal ranges of the elements are..
|
||||
|
||||
\code
|
||||
tm_sec seconds after the minute - [ 0 to 59 ]
|
||||
tm_min minutes after the hour - [ 0 to 59 ]
|
||||
tm_hour hours since midnight - [ 0 to 23 ]
|
||||
tm_mday day of the month - [ 1 to 31 ]
|
||||
tm_wday days since Sunday - [ 0 to 6 ]
|
||||
tm_mon months since January - [ 0 to 11 ]
|
||||
tm_year years since 1900
|
||||
tm_yday days since January 1 - [ 0 to 365 ]
|
||||
tm_isdst Daylight Saving Time flag *
|
||||
|
||||
\endcode
|
||||
|
||||
*The value of tm_isdst is zero if Daylight Saving Time is not in effect, and is negative if
|
||||
the information is not available.
|
||||
|
||||
When Daylight Saving Time is in effect, the value represents the number of
|
||||
seconds the clock is advanced.
|
||||
|
||||
See the set_dst() function for more information about Daylight Saving.
|
||||
|
||||
*/
|
||||
struct tm {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_wday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
};
|
||||
|
||||
|
||||
/* We have to provide clock_t / CLOCKS_PER_SEC so that libstdc++-v3 can
|
||||
be built. We define CLOCKS_PER_SEC via a symbol _CLOCKS_PER_SEC_
|
||||
so that the user can provide the value on the link line, which should
|
||||
result in little or no run-time overhead compared with a constant. */
|
||||
typedef unsigned long clock_t;
|
||||
extern char *_CLOCKS_PER_SEC_;
|
||||
#define CLOCKS_PER_SEC ((clock_t) _CLOCKS_PER_SEC_)
|
||||
extern clock_t clock(void);
|
||||
|
||||
/**
|
||||
This function 'compiles' the elements of a broken-down time structure, returning a binary time stamp.
|
||||
The elements of timeptr are interpreted as representing Local Time.
|
||||
|
||||
The original values of the tm_wday and tm_yday elements of the structure are ignored,
|
||||
and the original values of the other elements are not restricted to the ranges stated for struct tm.
|
||||
|
||||
On successful completion, the values of all elements of timeptr are set to the appropriate range.
|
||||
*/
|
||||
time_t mktime(struct tm * timeptr);
|
||||
|
||||
/**
|
||||
This function 'compiles' the elements of a broken-down time structure, returning a binary time stamp.
|
||||
The elements of timeptr are interpreted as representing UTC.
|
||||
|
||||
The original values of the tm_wday and tm_yday elements of the structure are ignored,
|
||||
and the original values of the other elements are not restricted to the ranges stated for struct tm.
|
||||
|
||||
Unlike mktime(), this function DOES NOT modify the elements of timeptr.
|
||||
*/
|
||||
time_t mk_gmtime(const struct tm * timeptr);
|
||||
|
||||
/**
|
||||
The gmtime function converts the time stamp pointed to by timer into broken-down time,
|
||||
expressed as UTC.
|
||||
*/
|
||||
struct tm *gmtime(const time_t * timer);
|
||||
|
||||
/**
|
||||
Re entrant version of gmtime().
|
||||
*/
|
||||
void gmtime_r(const time_t * timer, struct tm * timeptr);
|
||||
|
||||
/**
|
||||
The localtime function converts the time stamp pointed to by timer into broken-down time,
|
||||
expressed as Local time.
|
||||
*/
|
||||
struct tm *localtime(const time_t * timer);
|
||||
|
||||
/**
|
||||
Re entrant version of localtime().
|
||||
*/
|
||||
void localtime_r(const time_t * timer, struct tm * timeptr);
|
||||
|
||||
/**
|
||||
The asctime function converts the broken-down time of timeptr, into an ascii string in the form
|
||||
|
||||
Sun Mar 23 01:03:52 2013
|
||||
*/
|
||||
char *asctime(const struct tm * timeptr);
|
||||
|
||||
/**
|
||||
Re entrant version of asctime().
|
||||
*/
|
||||
void asctime_r(const struct tm * timeptr, char *buf);
|
||||
|
||||
/**
|
||||
The ctime function is equivalent to asctime(localtime(timer))
|
||||
*/
|
||||
char *ctime(const time_t * timer);
|
||||
|
||||
/**
|
||||
Re entrant version of ctime().
|
||||
*/
|
||||
void ctime_r(const time_t * timer, char *buf);
|
||||
|
||||
/**
|
||||
The isotime function constructs an ascii string in the form
|
||||
\code2013-03-23 01:03:52\endcode
|
||||
*/
|
||||
char *isotime(const struct tm * tmptr);
|
||||
|
||||
/**
|
||||
Re entrant version of isotime()
|
||||
*/
|
||||
void isotime_r(const struct tm *, char *);
|
||||
|
||||
/**
|
||||
A complete description of strftime() is beyond the pale of this document.
|
||||
Refer to ISO/IEC document 9899 for details.
|
||||
|
||||
All conversions are made using the 'C Locale', ignoring the E or O modifiers. Due to the lack of
|
||||
a time zone 'name', the 'Z' conversion is also ignored.
|
||||
*/
|
||||
size_t strftime(char *s, size_t maxsize, const char *format, const struct tm * timeptr);
|
||||
|
||||
/**
|
||||
Specify the Daylight Saving function.
|
||||
|
||||
The Daylight Saving function should examine its parameters to determine whether
|
||||
Daylight Saving is in effect, and return a value appropriate for tm_isdst.
|
||||
|
||||
Working examples for the USA and the EU are available..
|
||||
|
||||
\code #include <util/eu_dst.h>\endcode
|
||||
for the European Union, and
|
||||
\code #include <util/usa_dst.h>\endcode
|
||||
for the United States
|
||||
|
||||
If a Daylight Saving function is not specified, the system will ignore Daylight Saving.
|
||||
*/
|
||||
void set_dst(int (*) (const time_t *, int32_t *));
|
||||
|
||||
/**
|
||||
Set the 'time zone'. The parameter is given in seconds East of the Prime Meridian.
|
||||
Example for New York City:
|
||||
\code set_zone(-5 * ONE_HOUR);\endcode
|
||||
|
||||
If the time zone is not set, the time system will operate in UTC only.
|
||||
*/
|
||||
void set_zone(int32_t);
|
||||
|
||||
/**
|
||||
Initialize the system time. Examples are...
|
||||
|
||||
From a Clock / Calendar type RTC:
|
||||
\code
|
||||
struct tm rtc_time;
|
||||
|
||||
read_rtc(&rtc_time);
|
||||
rtc_time.tm_isdst = 0;
|
||||
set_system_time( mktime(&rtc_time) );
|
||||
\endcode
|
||||
|
||||
From a Network Time Protocol time stamp:
|
||||
\code
|
||||
set_system_time(ntp_timestamp - NTP_OFFSET);
|
||||
\endcode
|
||||
|
||||
From a UNIX time stamp:
|
||||
\code
|
||||
set_system_time(unix_timestamp - UNIX_OFFSET);
|
||||
\endcode
|
||||
|
||||
*/
|
||||
void set_system_time(time_t timestamp);
|
||||
|
||||
/**
|
||||
Maintain the system time by calling this function at a rate of 1 Hertz.
|
||||
|
||||
It is anticipated that this function will typically be called from within an
|
||||
Interrupt Service Routine, (though that is not required). It therefore includes code which
|
||||
makes it simple to use from within a 'Naked' ISR, avoiding the cost of saving and restoring
|
||||
all the cpu registers.
|
||||
|
||||
Such an ISR may resemble the following example...
|
||||
\code
|
||||
ISR(RTC_OVF_vect, ISR_NAKED)
|
||||
{
|
||||
system_tick();
|
||||
reti();
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
void system_tick(void);
|
||||
|
||||
/**
|
||||
Enumerated labels for the days of the week.
|
||||
*/
|
||||
enum _WEEK_DAYS_ {
|
||||
SUNDAY,
|
||||
MONDAY,
|
||||
TUESDAY,
|
||||
WEDNESDAY,
|
||||
THURSDAY,
|
||||
FRIDAY,
|
||||
SATURDAY
|
||||
};
|
||||
|
||||
/**
|
||||
Enumerated labels for the months.
|
||||
*/
|
||||
enum _MONTHS_ {
|
||||
JANUARY,
|
||||
FEBRUARY,
|
||||
MARCH,
|
||||
APRIL,
|
||||
MAY,
|
||||
JUNE,
|
||||
JULY,
|
||||
AUGUST,
|
||||
SEPTEMBER,
|
||||
OCTOBER,
|
||||
NOVEMBER,
|
||||
DECEMBER
|
||||
};
|
||||
|
||||
/**
|
||||
Return 1 if year is a leap year, zero if it is not.
|
||||
*/
|
||||
uint8_t is_leap_year(int16_t year);
|
||||
|
||||
/**
|
||||
Return the length of month, given the year and month, where month is in the range 1 to 12.
|
||||
*/
|
||||
uint8_t month_length(int16_t year, uint8_t month);
|
||||
|
||||
/**
|
||||
Return the calendar week of year, where week 1 is considered to begin on the
|
||||
day of week specified by 'start'. The returned value may range from zero to 52.
|
||||
*/
|
||||
uint8_t week_of_year(const struct tm * timeptr, uint8_t start);
|
||||
|
||||
/**
|
||||
Return the calendar week of month, where the first week is considered to begin on the
|
||||
day of week specified by 'start'. The returned value may range from zero to 5.
|
||||
*/
|
||||
uint8_t week_of_month(const struct tm * timeptr, uint8_t start);
|
||||
|
||||
/**
|
||||
Structure which represents a date as a year, week number of that year, and day of week.
|
||||
See http://en.wikipedia.org/wiki/ISO_week_date for more information.
|
||||
*/
|
||||
struct week_date{
|
||||
int year;
|
||||
int week;
|
||||
int day;
|
||||
};
|
||||
|
||||
/**
|
||||
Return a week_date structure with the ISO_8601 week based date corresponding to the given
|
||||
year and day of year. See http://en.wikipedia.org/wiki/ISO_week_date for more
|
||||
information.
|
||||
*/
|
||||
struct week_date * iso_week_date( int year, int yday);
|
||||
|
||||
/**
|
||||
Re-entrant version of iso-week_date.
|
||||
*/
|
||||
void iso_week_date_r( int year, int yday, struct week_date *);
|
||||
|
||||
/**
|
||||
Convert a Y2K time stamp into a FAT file system time stamp.
|
||||
*/
|
||||
uint32_t fatfs_time(const struct tm * timeptr);
|
||||
|
||||
/** One hour, expressed in seconds */
|
||||
#define ONE_HOUR 3600
|
||||
|
||||
/** Angular degree, expressed in arc seconds */
|
||||
#define ONE_DEGREE 3600
|
||||
|
||||
/** One day, expressed in seconds */
|
||||
#define ONE_DAY 86400
|
||||
|
||||
/** Difference between the Y2K and the UNIX epochs, in seconds. To convert a Y2K
|
||||
timestamp to UNIX...
|
||||
\code
|
||||
long unix;
|
||||
time_t y2k;
|
||||
|
||||
y2k = time(NULL);
|
||||
unix = y2k + UNIX_OFFSET;
|
||||
\endcode
|
||||
*/
|
||||
#define UNIX_OFFSET 946684800
|
||||
|
||||
/** Difference between the Y2K and the NTP epochs, in seconds. To convert a Y2K
|
||||
timestamp to NTP...
|
||||
\code
|
||||
unsigned long ntp;
|
||||
time_t y2k;
|
||||
|
||||
y2k = time(NULL);
|
||||
ntp = y2k + NTP_OFFSET;
|
||||
\endcode
|
||||
*/
|
||||
#define NTP_OFFSET 3155673600
|
||||
|
||||
/*
|
||||
* ===================================================================
|
||||
* Ephemera
|
||||
*/
|
||||
|
||||
/**
|
||||
Set the geographic coordinates of the 'observer', for use with several of the
|
||||
following functions. Parameters are passed as seconds of North Latitude, and seconds
|
||||
of East Longitude.
|
||||
|
||||
For New York City...
|
||||
\code set_position( 40.7142 * ONE_DEGREE, -74.0064 * ONE_DEGREE); \endcode
|
||||
*/
|
||||
void set_position(int32_t latitude, int32_t longitude);
|
||||
|
||||
/**
|
||||
Computes the difference between apparent solar time and mean solar time.
|
||||
The returned value is in seconds.
|
||||
*/
|
||||
int16_t equation_of_time(const time_t * timer);
|
||||
|
||||
/**
|
||||
Computes the amount of time the sun is above the horizon, at the location of the observer.
|
||||
|
||||
NOTE: At observer locations inside a polar circle, this value can be zero during the winter,
|
||||
and can exceed ONE_DAY during the summer.
|
||||
|
||||
The returned value is in seconds.
|
||||
*/
|
||||
int32_t daylight_seconds(const time_t * timer);
|
||||
|
||||
/**
|
||||
Computes the time of solar noon, at the location of the observer.
|
||||
*/
|
||||
time_t solar_noon(const time_t * timer);
|
||||
|
||||
/**
|
||||
Return the time of sunrise, at the location of the observer. See the note about daylight_seconds().
|
||||
*/
|
||||
time_t sun_rise(const time_t * timer);
|
||||
|
||||
/**
|
||||
Return the time of sunset, at the location of the observer. See the note about daylight_seconds().
|
||||
*/
|
||||
time_t sun_set(const time_t * timer);
|
||||
|
||||
/** Returns the declination of the sun in radians. */
|
||||
double solar_declination(const time_t * timer);
|
||||
|
||||
/**
|
||||
Returns an approximation to the phase of the moon.
|
||||
The sign of the returned value indicates a waning or waxing phase.
|
||||
The magnitude of the returned value indicates the percentage illumination.
|
||||
*/
|
||||
int8_t moon_phase(const time_t * timer);
|
||||
|
||||
/**
|
||||
Returns Greenwich Mean Sidereal Time, as seconds into the sidereal day.
|
||||
The returned value will range from 0 through 86399 seconds.
|
||||
*/
|
||||
unsigned long gm_sidereal(const time_t * timer);
|
||||
|
||||
/**
|
||||
Returns Local Mean Sidereal Time, as seconds into the sidereal day.
|
||||
The returned value will range from 0 through 86399 seconds.
|
||||
*/
|
||||
unsigned long lm_sidereal(const time_t * timer);
|
||||
|
||||
struct timespec {
|
||||
time_t tv_sec;
|
||||
long tv_nsec;
|
||||
};
|
||||
|
||||
/* @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TIME_H */
|
5
cpu/atmega_common/doc.txt
Normal file
5
cpu/atmega_common/doc.txt
Normal file
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* @defgroup cpu_atmega_common Atmel ATmega CPU: common files
|
||||
* @brief AVR Atmega specific code
|
||||
* @ingroup cpu
|
||||
*/
|
46
cpu/atmega_common/include/cpu.h
Normal file
46
cpu/atmega_common/include/cpu.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu
|
||||
* @brief Common implementations and headers for ATmega family based micro-controllers
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Basic definitions for the ATmega common module
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @author Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef __ATMEGA_COMMON_H
|
||||
#define __ATMEGA_COMMON_H
|
||||
|
||||
#include "cpu-conf.h"
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
/**
|
||||
* For downwards compatibility with old RIOT code.
|
||||
* TODO: remove once core was adjusted
|
||||
*/
|
||||
#include "irq.h"
|
||||
#define eINT enableIRQ
|
||||
#define dINT disableIRQ
|
||||
|
||||
/**
|
||||
* @brief Initialization of the CPU
|
||||
*/
|
||||
void cpu_init(void);
|
||||
|
||||
|
||||
#endif /* __ATMEGA_COMMON_H */
|
||||
/** @} */
|
15
cpu/atmega_common/include/sys/time.h
Normal file
15
cpu/atmega_common/include/sys/time.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct timeval {
|
||||
time_t tv_sec;
|
||||
suseconds_t tv_usec;
|
||||
};
|
13
cpu/atmega_common/include/sys/types.h
Normal file
13
cpu/atmega_common/include/sys/types.h
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef int16_t suseconds_t;
|
||||
typedef size_t ssize_t;
|
92
cpu/atmega_common/irq_arch.c
Normal file
92
cpu/atmega_common/irq_arch.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_atmega_common
|
||||
* @{
|
||||
*
|
||||
* @file irq_arch.c
|
||||
* @brief Implementation of the kernels irq interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "arch/irq_arch.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/**
|
||||
* @brief Macro returns state of the global interrupt register
|
||||
*/
|
||||
static uint8_t __get_interrupt_state(void);
|
||||
static void __set_interrupt_state(uint8_t state);
|
||||
|
||||
__attribute__((always_inline)) static inline uint8_t __get_interrupt_state(void)
|
||||
{
|
||||
uint8_t sreg;
|
||||
asm volatile("in r0, __SREG__; \n\t"
|
||||
"mov %0, r0 \n\t"
|
||||
: "=g"(sreg)
|
||||
:
|
||||
: "r0");
|
||||
return sreg & (1 << 7);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline void __set_interrupt_state(uint8_t state)
|
||||
{
|
||||
asm volatile("mov r15,%0; \n\t"
|
||||
"in r16, __SREG__; \n\t"
|
||||
"cbr r16,7; \n\t"
|
||||
"or r15,r16; \n\t"
|
||||
"out __SREG__, r15 \n\t"
|
||||
:
|
||||
: "g"(state)
|
||||
: "r15", "r16");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all maskable interrupts
|
||||
*/
|
||||
unsigned int irq_arch_disable(void)
|
||||
{
|
||||
uint8_t mask = __get_interrupt_state();
|
||||
cli();
|
||||
return (unsigned int) mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all maskable interrupts
|
||||
*/
|
||||
unsigned int irq_arch_enable(void)
|
||||
{
|
||||
sei();
|
||||
return __get_interrupt_state();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restore the state of the IRQ flags
|
||||
*/
|
||||
void irq_arch_restore(unsigned int state)
|
||||
{
|
||||
__set_interrupt_state(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief See if the current context is inside an ISR
|
||||
*/
|
||||
int irq_arch_in(void)
|
||||
{
|
||||
/*
|
||||
* TODO: find a way to implement this function (e.g. a static variable dis- or
|
||||
* set and unset in each ISR)
|
||||
*/
|
||||
return 0;
|
||||
}
|
344
cpu/atmega_common/thread_arch.c
Normal file
344
cpu/atmega_common/thread_arch.c
Normal file
@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_atmega_common
|
||||
* @{
|
||||
*
|
||||
* @file thread_arch.c
|
||||
* @brief Implementation of the kernel's architecture dependent thread interface
|
||||
*
|
||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "arch/thread_arch.h"
|
||||
#include "thread.h"
|
||||
#include "sched.h"
|
||||
#include "irq.h"
|
||||
#include "cpu.h"
|
||||
#include "kernel_internal.h"
|
||||
|
||||
/*
|
||||
* local function declarations (prefixed with __)
|
||||
*/
|
||||
|
||||
static void __context_save(void);
|
||||
static void __context_restore(void);
|
||||
static void __enter_thread_mode(void);
|
||||
|
||||
/**
|
||||
* @brief Since AVR doesn't support direct manipulation of the program counter we
|
||||
* model a stack like it would be left by __context_save().
|
||||
* The resulting layout in memory is the following:
|
||||
* ---------------tcb_t (not created by thread_arch_stack_init) ----------
|
||||
* local variables (a temporary value and the stackpointer)
|
||||
* -----------------------------------------------------------------------
|
||||
* a marker (AFFE) - for debugging purposes (helps finding the stack
|
||||
* -----------------------------------------------------------------------
|
||||
* a 16 Bit pointer to sched_task_exit
|
||||
* (Optional 17 bit (bit is set to zero) for ATmega2560
|
||||
* -----------------------------------------------------------------------
|
||||
* a 16 Bit pointer to task_func
|
||||
* this is placed exactly at the place where the program counter would be
|
||||
* stored normally and thus can be returned to when __context_restore()
|
||||
* has been run
|
||||
* (Optional 17 bit (bit is set to zero) for ATmega2560
|
||||
* -----------------------------------------------------------------------
|
||||
* saved registers from context:
|
||||
* r0
|
||||
* status register
|
||||
* (Optional EIND and RAMPZ registers for ATmega2560)
|
||||
* r1 - r23
|
||||
* pointer to arg in r24 and r25
|
||||
* r26 - r31
|
||||
* -----------------------------------------------------------------------
|
||||
*
|
||||
* After the invocation of __context_restore() the pointer to task_func is
|
||||
* on top of the stack and can be returned to. This way we can actually place
|
||||
* it inside of the programm counter of the MCU.
|
||||
* if task_func returns sched_task_exit gets popped into the PC
|
||||
*/
|
||||
char *thread_arch_stack_init(void *(*task_func)(void *), void *arg, void *stack_start,
|
||||
int stack_size)
|
||||
{
|
||||
uint16_t tmp_adress;
|
||||
uint8_t *stk;
|
||||
|
||||
/* AVR uses 16 Bit or two 8 Bit registers for storing pointers*/
|
||||
stk = (uint8_t *)((uint16_t)stack_start + stack_size);
|
||||
|
||||
/* put marker on stack */
|
||||
stk--;
|
||||
*stk = (uint8_t) 0xAF;
|
||||
stk--;
|
||||
*stk = (uint8_t) 0xFE;
|
||||
|
||||
/* save sched_task_exit */
|
||||
stk--;
|
||||
tmp_adress = (uint16_t) sched_task_exit;
|
||||
*stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff);
|
||||
stk--;
|
||||
tmp_adress >>= 8;
|
||||
*stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff);
|
||||
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
/* The ATMega2560 uses a 17 bit PC, we set whole the top byte forcibly to 0 */
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x00;
|
||||
#endif
|
||||
|
||||
/* save address to task_func in place of the program counter */
|
||||
stk--;
|
||||
tmp_adress = (uint16_t) task_func;
|
||||
*stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff);
|
||||
stk--;
|
||||
tmp_adress >>= 8;
|
||||
*stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff);
|
||||
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
/* The ATMega2560 uses a 17 byte PC, we set the top byte forcibly to 0 */
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x00;
|
||||
#endif
|
||||
|
||||
|
||||
/* r0 */
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x00;
|
||||
|
||||
/* status register (with interrupts enabled) */
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x80;
|
||||
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
/* EIND */
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x00;
|
||||
|
||||
/* RAMPZ */
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x00;
|
||||
#endif
|
||||
|
||||
/* r1 - has always to be 0 */
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x00;
|
||||
/*
|
||||
* Space for registers r2 -r23
|
||||
*
|
||||
* use loop for better readability, the compiler unrolls anyways
|
||||
*/
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 2; i <= 23 ; i++) {
|
||||
stk--;
|
||||
*stk = (uint8_t) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* In accordance with the AVR calling conventions *arg has to be inside
|
||||
* r24 and r25
|
||||
* */
|
||||
stk--;
|
||||
tmp_adress = (uint16_t) arg;
|
||||
*stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff);
|
||||
stk--;
|
||||
tmp_adress >>= 8;
|
||||
*stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff);
|
||||
|
||||
/*
|
||||
* Space for registers r26-r31
|
||||
*/
|
||||
for (i = 26; i <= 31; i++) {
|
||||
stk--;
|
||||
*stk = (uint8_t) i;
|
||||
}
|
||||
|
||||
stk--;
|
||||
return (char *) stk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief thread_arch_stack_print prints the stack to stdout.
|
||||
* It depends on getting the correct values for stack_start, stack_size and sp
|
||||
* from sched_active_thread.
|
||||
* Maybe it would be good to change that to way that is less dependant on
|
||||
* getting correct values elsewhere (since it is a debugging tool and in the
|
||||
* presence of bugs the data may be corrupted).
|
||||
*/
|
||||
void thread_arch_stack_print(void)
|
||||
{
|
||||
uint8_t found_marker = 1;
|
||||
uint8_t *sp = (uint8_t *)sched_active_thread->sp;
|
||||
uint16_t size = 0;
|
||||
|
||||
printf("Printing current stack of thread %" PRIkernel_pid "\n", thread_getpid());
|
||||
printf("\taddress:\tdata:\n");
|
||||
|
||||
do {
|
||||
printf("\t0x%04x:\t\t0x%04x\n", (unsigned int)sp, (unsigned int)*sp);
|
||||
sp++;
|
||||
size++;
|
||||
|
||||
if ((*sp == 0xFE) && (*(sp + 1) == 0xAF)) {
|
||||
found_marker = 0;
|
||||
}
|
||||
}
|
||||
while (found_marker == 1);
|
||||
|
||||
printf("stack size: %u bytes\n", size);
|
||||
}
|
||||
|
||||
void thread_arch_start_threading(void) __attribute__((naked));
|
||||
void thread_arch_start_threading(void)
|
||||
{
|
||||
sched_run();
|
||||
__enter_thread_mode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the MCU into Thread-Mode and load the initial task from the stack and run it
|
||||
*/
|
||||
|
||||
void NORETURN __enter_thread_mode(void) __attribute__((naked));
|
||||
void NORETURN __enter_thread_mode(void)
|
||||
{
|
||||
enableIRQ();
|
||||
__context_restore();
|
||||
asm volatile("ret");
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void thread_arch_yield(void) __attribute__((naked));
|
||||
void thread_arch_yield(void)
|
||||
{
|
||||
__context_save();
|
||||
|
||||
/* disableIRQ(); */ /* gets already disabled during __context_save() */
|
||||
sched_run();
|
||||
enableIRQ();
|
||||
|
||||
__context_restore();
|
||||
asm volatile("ret");
|
||||
}
|
||||
|
||||
|
||||
__attribute__((always_inline)) static inline void __context_save(void)
|
||||
{
|
||||
asm volatile(
|
||||
"push r0 \n\t"
|
||||
"in r0, __SREG__ \n\t"
|
||||
"cli \n\t"
|
||||
"push r0 \n\t"
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
/* EIND and RAMPZ */
|
||||
"in r0, 0x3b \n\t"
|
||||
"push r0 \n\t"
|
||||
"in r0, 0x3c \n\t"
|
||||
"push r0 \n\t"
|
||||
#endif
|
||||
"push r1 \n\t"
|
||||
"clr r1 \n\t"
|
||||
"push r2 \n\t"
|
||||
"push r3 \n\t"
|
||||
"push r4 \n\t"
|
||||
"push r5 \n\t"
|
||||
"push r6 \n\t"
|
||||
"push r7 \n\t"
|
||||
"push r8 \n\t"
|
||||
"push r9 \n\t"
|
||||
"push r10 \n\t"
|
||||
"push r11 \n\t"
|
||||
"push r12 \n\t"
|
||||
"push r13 \n\t"
|
||||
"push r14 \n\t"
|
||||
"push r15 \n\t"
|
||||
"push r16 \n\t"
|
||||
"push r17 \n\t"
|
||||
"push r18 \n\t"
|
||||
"push r19 \n\t"
|
||||
"push r20 \n\t"
|
||||
"push r21 \n\t"
|
||||
"push r22 \n\t"
|
||||
"push r23 \n\t"
|
||||
"push r24 \n\t"
|
||||
"push r25 \n\t"
|
||||
"push r26 \n\t"
|
||||
"push r27 \n\t"
|
||||
"push r28 \n\t"
|
||||
"push r29 \n\t"
|
||||
"push r30 \n\t"
|
||||
"push r31 \n\t"
|
||||
"lds r26, sched_active_thread \n\t"
|
||||
"lds r27, sched_active_thread + 1 \n\t"
|
||||
"in r0, __SP_L__ \n\t"
|
||||
"st x+, r0 \n\t"
|
||||
"in r0, __SP_H__ \n\t"
|
||||
"st x+, r0 \n\t"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void __context_restore(void)
|
||||
{
|
||||
asm volatile(
|
||||
"lds r26, sched_active_thread \n\t"
|
||||
"lds r27, sched_active_thread + 1 \n\t"
|
||||
"ld r28, x+ \n\t"
|
||||
"out __SP_L__, r28 \n\t"
|
||||
"ld r29, x+ \n\t"
|
||||
"out __SP_H__, r29 \n\t"
|
||||
"pop r31 \n\t"
|
||||
"pop r30 \n\t"
|
||||
"pop r29 \n\t"
|
||||
"pop r28 \n\t"
|
||||
"pop r27 \n\t"
|
||||
"pop r26 \n\t"
|
||||
"pop r25 \n\t"
|
||||
"pop r24 \n\t"
|
||||
"pop r23 \n\t"
|
||||
"pop r22 \n\t"
|
||||
"pop r21 \n\t"
|
||||
"pop r20 \n\t"
|
||||
"pop r19 \n\t"
|
||||
"pop r18 \n\t"
|
||||
"pop r17 \n\t"
|
||||
"pop r16 \n\t"
|
||||
"pop r15 \n\t"
|
||||
"pop r14 \n\t"
|
||||
"pop r13 \n\t"
|
||||
"pop r12 \n\t"
|
||||
"pop r11 \n\t"
|
||||
"pop r10 \n\t"
|
||||
"pop r9 \n\t"
|
||||
"pop r8 \n\t"
|
||||
"pop r7 \n\t"
|
||||
"pop r6 \n\t"
|
||||
"pop r5 \n\t"
|
||||
"pop r4 \n\t"
|
||||
"pop r3 \n\t"
|
||||
"pop r2 \n\t"
|
||||
"pop r1 \n\t"
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
/* EIND and RAMPZ */
|
||||
"pop r0 \n\t"
|
||||
"out 0x3c, r0 \n\t"
|
||||
"pop r0 \n\t"
|
||||
"out 0x3b, r0 \n\t"
|
||||
#endif
|
||||
"pop r0 \n\t"
|
||||
"out __SREG__, r0 \n\t"
|
||||
"pop r0 \n\t"
|
||||
);
|
||||
}
|
1
dist/tools/licenses/patterns/mod-BSD-avr-libc
vendored
Normal file
1
dist/tools/licenses/patterns/mod-BSD-avr-libc
vendored
Normal file
@ -0,0 +1 @@
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\. * Redistributions in binary form must reproduce the above copyright notice\, this list of conditions and the following disclaimer in the documentation and.or other materials provided with the distribution\. * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\.
|
Loading…
Reference in New Issue
Block a user