Merge pull request #1816 from bthebaudeau/cm-cc2538-mt

Cortex-M and CC2538 multi-threading
This commit is contained in:
Benoît Thébaudeau 2016-11-24 23:28:05 +01:00 committed by GitHub
commit 52a8dcc65b
67 changed files with 11378 additions and 5968 deletions

View file

@ -68,14 +68,13 @@ mt_start(struct mt_thread *thread, void (* function)(void *), void *data)
stack with the correct parameters. */
mtarch_start(&thread->thread, function, data);
thread->state = MT_STATE_READY;
thread->state = MT_STATE_STARTED;
}
/*--------------------------------------------------------------------------*/
void
mt_exec(struct mt_thread *thread)
{
if(thread->state == MT_STATE_READY) {
thread->state = MT_STATE_RUNNING;
if(thread->state == MT_STATE_STARTED) {
current = thread;
/* Switch context to the thread. The function call will not return
until the the thread has yielded, or is preempted. */
@ -87,21 +86,18 @@ void
mt_yield(void)
{
mtarch_pstop();
current->state = MT_STATE_READY;
current = NULL;
/* This function is called from the running thread, and we call the
switch function in order to switch the thread to the main Contiki
program instead. For us, the switch function will not return
until the next time we are scheduled to run. */
mtarch_yield();
}
/*--------------------------------------------------------------------------*/
void
mt_exit(void)
{
mtarch_pstop();
current->state = MT_STATE_EXITED;
current = NULL;
mtarch_yield();
}
/*--------------------------------------------------------------------------*/

View file

@ -84,9 +84,8 @@
#include "contiki.h"
#define MT_STATE_READY 1
#define MT_STATE_RUNNING 2
#define MT_STATE_EXITED 5
#define MT_STATE_STARTED 1
#define MT_STATE_EXITED 2
/**
* An opaque structure that is used for holding the state of a thread.
@ -183,18 +182,9 @@ void mtarch_pstop(void);
struct mt_thread {
int state;
process_event_t *evptr;
process_data_t *dataptr;
struct mtarch_thread thread;
};
/**
* No error.
*
* \hideinitializer
*/
#define MT_OK 1
/**
* Initializes the multithreading library.
*

View file

@ -1,19 +1,19 @@
/**
* @defgroup cmsis CMSIS (Cortex Microcontroller Software Interface Standard)
* @ingroup arm
* \defgroup cmsis CMSIS (Cortex Microcontroller Software Interface Standard)
* \ingroup arm
*/
/**
* @defgroup aducrf101 ADUCRF101
* @ingroup arm
* \defgroup aducrf101 ADUCRF101
* \ingroup arm
*/
/**
* @defgroup at91sam7s AT91SAM7S
* @ingroup arm
* \defgroup at91sam7s AT91SAM7S
* \ingroup arm
*/
/**
* @defgroup stm32f103 STM32F103
* @ingroup arm
* \defgroup stm32f103 STM32F103
* \ingroup arm
*/

View file

@ -0,0 +1,734 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS Cortex-M Core Function/Instruction Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
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 ARM nor the names of its 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#ifndef __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get Base Priority
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
/**
\brief Wait For Event
\details Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/**
\brief Send Event
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
#define __ISB() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order in signed short value
\details Reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return(result);
}
#endif
/**
\brief Count leading zeros
\details Counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/**
\brief Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#endif /* (__CORTEX_M >= 0x04) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,50 +1,59 @@
/**
* @addtogroup CMSIS_Core_FunctionInterface
* @ingroup cmsis
* \addtogroup CMSIS_Core_FunctionInterface
* \ingroup cmsis
*/
/**
* @addtogroup CMSIS_core_register
* @ingroup cmsis
* \addtogroup CMSIS_core_register
* \ingroup cmsis
*/
/**
* @addtogroup CMSIS_glob_defs
* @ingroup cmsis
* \addtogroup CMSIS_glob_defs
* \ingroup cmsis
*/
/**
* @addtogroup CMSIS_MISRA_Exceptions
* @ingroup cmsis
* \addtogroup CMSIS_MISRA_Exceptions
* \ingroup cmsis
*/
/**
* @addtogroup CMSIS_core_definitions
* @ingroup cmsis
* \addtogroup CMSIS_core_definitions
* \ingroup cmsis
*/
/**
* @addtogroup CMSIS_SIMD_intrinsics
* @ingroup cmsis
* \addtogroup CMSIS_SIMD_intrinsics
* \ingroup cmsis
*/
/**
* @addtogroup CMSIS_Core_InstructionInterface
* @ingroup cmsis
* \addtogroup CMSIS_Core_InstructionInterface
* \ingroup cmsis
*/
/**
* @defgroup Cortex_M0 Cortex-M0
* @ingroup cmsis
* \defgroup Cortex_M0 Cortex-M0
* \ingroup cmsis
*/
/**
* @defgroup Cortex_M3 Cortex-M3
* @ingroup cmsis
* \defgroup Cortex-M0+ Cortex-M0+
* \ingroup cmsis
*/
/**
* @defgroup Cortex_M4 Cortex-M4
* @ingroup cmsis
* \defgroup Cortex_M3 Cortex-M3
* \ingroup cmsis
*/
/**
* \defgroup Cortex_M4 Cortex-M4
* \ingroup cmsis
*/
/**
* \defgroup Cortex_M7 Cortex-M7
* \ingroup cmsis
*/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,697 +0,0 @@
/**************************************************************************//**
* @file core_cm4_simd.h
* @brief CMSIS Cortex-M4 SIMD Header File
* @version V3.30
* @date 17. February 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
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 ARM nor the names of its 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifndef __CORE_CM4_SIMD_H
#define __CORE_CM4_SIMD_H
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Hardware Abstraction Layer
******************************************************************************/
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32) ) >> 32))
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SSAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
#define __USAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
#define __PKHBT(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
#define __PKHTB(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
if (ARG3 == 0) \
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
else \
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
{
int32_t result;
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/* not yet supported */
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM4_SIMD_H */

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,10 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.30
* @date 17. February 2014
*
* @note
*
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -35,6 +32,12 @@
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
@ -43,592 +46,39 @@
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
__ASM volatile ("");
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
__ASM volatile ("");
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif

View file

@ -1,13 +1,10 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.30
* @date 17. February 2014
*
* @note
*
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -35,6 +32,12 @@
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
@ -45,640 +48,37 @@
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/* Define macros for porting to both thumb1 and thumb2.
* For thumb1, use low register (r0-r7), specified by constrant "l"
* Otherwise, use general registers, specified by constrant "r" */
#if defined (__thumb__) && !defined (__thumb2__)
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
#define __CMSIS_GCC_USE_REG(r) "l" (r)
#else
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
#define __CMSIS_GCC_USE_REG(r) "r" (r)
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
return __builtin_bswap32(value);
#else
uint32_t result;
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
return (short)__builtin_bswap16(value);
#else
uint32_t result;
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << (32 - op2));
}
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex" ::: "memory");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint32_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return ((uint8_t) result); /* Add explicit type cast here */
}
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif

View file

@ -0,0 +1,96 @@
/**************************************************************************//**
* @file core_cmSimd.h
* @brief CMSIS Cortex-M SIMD Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
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 ARM nor the names of its 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMSIMD_H
#define __CORE_CMSIMD_H
#ifdef __cplusplus
extern "C" {
#endif
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CMSIMD_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

285
cpu/arm/common/sys/mtarch.c Normal file
View file

@ -0,0 +1,285 @@
/*
* Copyright (c) 2016, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. Neither the name of the copyright holder nor the names of its 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 HOLDER 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.
*/
/**
* \addtogroup arm-cm-mtarch
* @{
*
* \file
* Implmentation of the ARM Cortex-M support for Contiki multi-threading.
*/
#include CMSIS_DEV_HDR
#include "sys/mt.h"
#include <stdint.h>
#define EXC_RETURN_PROCESS_THREAD_BASIC_FRAME 0xfffffffd
/* Check whether EXC_RETURN[3:0] in LR indicates a preempted process thread. */
#if __ARM_ARCH == 7
#define PREEMPTED_PROCESS_THREAD() \
"and r0, lr, #0xf\n\t" \
"cmp r0, #0xd\n\t"
#elif __ARM_ARCH == 6
#define PREEMPTED_PROCESS_THREAD() \
"mov r0, lr\n\t" \
"movs r1, #0xf\n\t" \
"and r0, r1\n\t" \
"cmp r0, #0xd\n\t"
#else
#error Unsupported ARM architecture
#endif
/*----------------------------------------------------------------------------*/
/**
* \brief SVCall system handler
*
* This exception handler executes the action requested by the corresponding
* \c svc instruction, which is a task switch from the main Contiki thread to an
* mt thread or the other way around.
*/
__attribute__ ((__naked__))
void
svcall_handler(void)
{
/* This is a controlled system handler, so do not use ENERGEST_TYPE_IRQ. */
/*
* Decide whether to switch to the main thread or to a process thread,
* depending on the type of the thread preempted by SVCall.
*/
__asm__ (PREEMPTED_PROCESS_THREAD()
#if __ARM_ARCH == 7
"it eq\n\t"
#endif
"beq switch_to_main_thread\n\t"
/*
* - Retrieve from the main stack the PSP passed to SVCall through R0. Note
* that it cannot be retrieved directly from R0 on exception entry because
* this register may have been overwritten by other exceptions on SVCall
* entry.
* - Save the main thread context to the main stack.
* - Restore the process thread context from the process stack.
* - Return to Thread mode, resuming the process thread.
*/
#if __ARM_ARCH == 7
"ldr r0, [sp]\n\t"
"push {r4-r11, lr}\n\t"
"add r1, r0, #9 * 4\n\t"
"msr psp, r1\n\t"
"ldmia r0, {r4-r11, pc}");
#elif __ARM_ARCH == 6
"mov r0, r8\n\t"
"mov r1, r9\n\t"
"mov r2, r10\n\t"
"mov r3, r11\n\t"
"push {r0-r7, lr}\n\t"
"ldr r0, [sp, #9 * 4]\n\t"
"ldmia r0!, {r4-r7}\n\t"
"mov r8, r4\n\t"
"mov r9, r5\n\t"
"mov r10, r6\n\t"
"mov r11, r7\n\t"
"ldmia r0!, {r3-r7}\n\t"
"msr psp, r0\n\t"
"bx r3");
#endif
}
/*----------------------------------------------------------------------------*/
/**
* \brief PendSV system handler
*
* This exception handler executes following a call to mtarch_pstart() from
* another exception handler. It performs a task switch to the main Contiki
* thread if it is not already running.
*/
__attribute__ ((__naked__))
void
pendsv_handler(void)
{
/* This is a controlled system handler, so do not use ENERGEST_TYPE_IRQ. */
/*
* Return without doing anything if PendSV has not preempted a process thread.
* This can occur either because PendSV has preempted the main thread, in
* which case there is nothing to do, or because mtarch_pstart() has been
* called from an exception handler without having called mt_init() first, in
* which case PendSV may have preempted an exception handler and nothing must
* be done because mt is not active.
*/
__asm__ ( PREEMPTED_PROCESS_THREAD()
#if __ARM_ARCH == 7
"it ne\n\t"
"bxne lr\n"
#elif __ARM_ARCH == 6
"beq switch_to_main_thread\n\t"
"bx lr\n"
#endif
/*
* - Save the process thread context to the process stack.
* - Place into the main stack the updated PSP that SVCall must return through
* R0.
* - Restore the main thread context from the main stack.
* - Return to Thread mode, resuming the main thread.
*/
"switch_to_main_thread:\n\t"
"mrs r0, psp\n\t"
#if __ARM_ARCH == 7
"stmdb r0!, {r4-r11, lr}\n\t"
"str r0, [sp, #9 * 4]\n\t"
"pop {r4-r11, pc}");
#elif __ARM_ARCH == 6
"mov r3, lr\n\t"
"sub r0, #5 * 4\n\t"
"stmia r0!, {r3-r7}\n\t"
"mov r4, r8\n\t"
"mov r5, r9\n\t"
"sub r0, #9 * 4\n\t"
"mov r6, r10\n\t"
"mov r7, r11\n\t"
"stmia r0!, {r4-r7}\n\t"
"pop {r4-r7}\n\t"
"sub r0, #4 * 4\n\t"
"mov r8, r4\n\t"
"mov r9, r5\n\t"
"str r0, [sp, #5 * 4]\n\t"
"mov r10, r6\n\t"
"mov r11, r7\n\t"
"pop {r4-r7, pc}");
#endif
}
/*----------------------------------------------------------------------------*/
void
mtarch_init(void)
{
SCB->CCR = (SCB->CCR
#ifdef SCB_CCR_NONBASETHRDENA_Msk
/*
* Make sure that any attempt to enter Thread mode with exceptions
* active faults.
*
* Only SVCall and PendSV are allowed to forcibly enter Thread
* mode, and they are configured with the same, lowest exception
* priority, so no other exceptions may be active.
*/
& ~SCB_CCR_NONBASETHRDENA_Msk
#endif
/*
* Force 8-byte stack pointer alignment on exception entry in order
* to be able to use AAPCS-conforming functions as exception
* handlers.
*/
) | SCB_CCR_STKALIGN_Msk;
/*
* Configure SVCall and PendSV with the same, lowest exception priority.
*
* This makes sure that they cannot preempt each other, and that the processor
* executes them after having handled all other exceptions. If both are
* pending at the same time, then SVCall takes precedence because of its lower
* exception number. In addition, the associated exception handlers do not
* have to check whether they are returning to Thread mode, because they
* cannot preempt any other exception.
*/
NVIC_SetPriority(SVCall_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
/*
* Force the preceding configurations to take effect before further
* operations.
*/
__DSB();
__ISB();
}
/*----------------------------------------------------------------------------*/
void
mtarch_start(struct mtarch_thread *thread,
void (*function)(void *data), void *data)
{
struct mtarch_thread_context *context = &thread->start_stack.context;
/*
* Initialize the thread context with the appropriate values to call
* function() with data and to make function() return to mt_exit() without
* having to call it explicitly.
*/
context->exc_return = EXC_RETURN_PROCESS_THREAD_BASIC_FRAME;
context->r0 = (uint32_t)data;
context->lr = (uint32_t)mt_exit;
context->pc = (uint32_t)function;
context->xpsr = xPSR_T_Msk;
thread->psp = (uint32_t)context;
}
/*----------------------------------------------------------------------------*/
void
mtarch_exec(struct mtarch_thread *thread)
{
/* Pass the PSP to SVCall, and get the updated PSP as its return value. */
register uint32_t psp __asm__ ("r0") = thread->psp;
__asm__ volatile ("svc #0"
: "+r" (psp)
:: "memory");
thread->psp = psp;
}
/*----------------------------------------------------------------------------*/
__attribute__ ((__naked__))
void
mtarch_yield(void)
{
/* Invoke SVCall. */
__asm__ ("svc #0\n\t"
"bx lr");
}
/*----------------------------------------------------------------------------*/
void
mtarch_stop(struct mtarch_thread *thread)
{
}
/*----------------------------------------------------------------------------*/
void
mtarch_pstart(void)
{
/* Trigger PendSV. */
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
}
/*----------------------------------------------------------------------------*/
void
mtarch_pstop(void)
{
}
/*----------------------------------------------------------------------------*/
void
mtarch_remove(void)
{
}
/*----------------------------------------------------------------------------*/
/** @} */

119
cpu/arm/common/sys/mtarch.h Normal file
View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2016, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. Neither the name of the copyright holder nor the names of its 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 HOLDER 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.
*/
/**
* \addtogroup arm
* @{
*
* \defgroup arm-cm-mtarch ARM Cortex-M support for Contiki multi-threading
*
* All the Cortex-M devices supported by CMSIS-CORE are supported.
*
* An exception handler can decide to make the main Contiki thread preempt any
* running mt thread by calling mtarch_pstart() (e.g. to perform urgent
* operations that have been triggered by some event or that had been
* scheduled). If the running thread is already the main Contiki thread, then
* nothing happens. The corresponding task switch takes place when leaving
* Handler mode. The main Contiki thread then resumes after the call to
* mt_exec() that yielded to the preempted mt thread.
* @{
*
* \file
* Header file for the ARM Cortex-M support for Contiki multi-threading.
*/
#ifndef MTARCH_H_
#define MTARCH_H_
#include "contiki-conf.h"
#include "sys/cc.h"
#include <stdint.h>
#ifndef MTARCH_CONF_STACKSIZE
/** Thread stack size configuration, expressed as a number of 32-bit words. */
#define MTARCH_CONF_STACKSIZE 256
#endif
/** Actual stack size, with minimum size and alignment requirements enforced. */
#define MTARCH_STACKSIZE ((MAX(MTARCH_CONF_STACKSIZE, \
sizeof(struct mtarch_thread_context) / \
sizeof(uint32_t)) + 1) & ~1)
/**
* Structure of a saved thread context.
*
* <tt>xpsr..r0</tt> are managed by the processor (except in mtarch_start()),
* while the other register values are handled by the software.
*/
struct mtarch_thread_context {
#if __ARM_ARCH == 7
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
#endif
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t exc_return;
#if __ARM_ARCH == 6
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
#endif
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t xpsr;
};
struct mtarch_thread {
uint32_t psp;
union {
struct {
uint32_t free[MTARCH_STACKSIZE -
sizeof(struct mtarch_thread_context) / sizeof(uint32_t)];
struct mtarch_thread_context context;
} start_stack;
uint32_t stack[MTARCH_STACKSIZE];
} CC_ALIGN(8);
};
#endif /* MTARCH_H_ */
/**
* @}
* @}
*/

View file

@ -14,7 +14,7 @@ LDSCRIPT = $(OBJECTDIR)/cc2538.ld
CFLAGS += -mcpu=cortex-m3 -mthumb -mlittle-endian
CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -fshort-enums -fomit-frame-pointer -fno-strict-aliasing
CFLAGS += -Wall
CFLAGS += -Wall -DCMSIS_DEV_HDR=\"cc2538_cm3.h\"
LDFLAGS += -mcpu=cortex-m3 -mthumb -nostartfiles
LDFLAGS += -T $(LDSCRIPT)
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
@ -42,7 +42,7 @@ endif
CLEAN += symbols.c symbols.h *.d *.elf *.hex
### CPU-dependent directories
CONTIKI_CPU_DIRS = . dev usb
CONTIKI_CPU_DIRS = ../arm/common/CMSIS . dev usb
### Use the existing debug I/O in cpu/arm/common
CONTIKI_CPU_DIRS += ../arm/common/dbg-io
@ -52,7 +52,7 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm
### CPU-dependent source files
CONTIKI_CPU_SOURCEFILES += soc.c clock.c rtimer-arch.c uart.c watchdog.c
CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
CONTIKI_CPU_SOURCEFILES += nvic.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c cbc-mac.c gcm.c
CONTIKI_CPU_SOURCEFILES += ccm.c sha256.c
CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c
@ -79,7 +79,7 @@ CPU_STARTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(CPU_START_SOURCEFILES
CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES)
CONTIKI_SOURCEFILES += $(USB_CORE_SOURCEFILES) $(USB_ARCH_SOURCEFILES)
MODULES += lib/newlib
MODULES += lib/newlib cpu/arm/common/sys
.SECONDEXPANSION:
@ -123,4 +123,4 @@ LDGENFLAGS += -x c -P -E
# NB: Assumes LDSCRIPT was not overridden and is in $(OBJECTDIR)
$(LDSCRIPT): $(SOURCE_LDSCRIPT) FORCE | $(OBJECTDIR)
$(TRACE_CC)
$(Q)$(CC) $(LDGENFLAGS) $< -o $@
$(Q)$(CC) $(LDGENFLAGS) $< | grep -v '^\s*#\s*pragma\>' > $@

144
cpu/cc2538/cc2538_cm3.h Normal file
View file

@ -0,0 +1,144 @@
/*
* Template:
* Copyright (c) 2012 ARM LIMITED
* All rights reserved.
*
* CC2538:
* Copyright (c) 2016, Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. Neither the name of the copyright holder nor the names of its 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 HOLDER 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.
*/
/**
* \addtogroup cc2538
* @{
*
* \defgroup cc2538-cm3 CC2538 Cortex-M3
*
* CC2538 Cortex-M3 CMSIS definitions
* @{
*
* \file
* CMSIS Cortex-M3 core peripheral access layer header file for CC2538
*/
#ifndef CC2538_CM3_H
#define CC2538_CM3_H
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup CC2538_CMSIS CC2538 CMSIS Definitions
* Configuration of the Cortex-M3 Processor and Core Peripherals
* @{
*/
/** \name Interrupt Number Definition
* @{
*/
typedef enum IRQn
{
/****** Cortex-M3 Processor Exceptions Numbers ****************************/
NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */
HardFault_IRQn = -13, /**< 3 HardFault Interrupt */
MemoryManagement_IRQn = -12, /**< 4 Memory Management Interrupt */
BusFault_IRQn = -11, /**< 5 Bus Fault Interrupt */
UsageFault_IRQn = -10, /**< 6 Usage Fault Interrupt */
SVCall_IRQn = -5, /**< 11 SV Call Interrupt */
DebugMonitor_IRQn = -4, /**< 12 Debug Monitor Interrupt */
PendSV_IRQn = -2, /**< 14 Pend SV Interrupt */
SysTick_IRQn = -1, /**< 15 System Tick Interrupt */
/****** CC2538-Specific Interrupt Numbers *********************************/
GPIO_A_IRQn = 0, /**< GPIO port A Interrupt */
GPIO_B_IRQn = 1, /**< GPIO port B Interrupt */
GPIO_C_IRQn = 2, /**< GPIO port C Interrupt */
GPIO_D_IRQn = 3, /**< GPIO port D Interrupt */
UART0_IRQn = 5, /**< UART0 Interrupt */
UART1_IRQn = 6, /**< UART1 Interrupt */
SSI0_IRQn = 7, /**< SSI0 Interrupt */
I2C_IRQn = 8, /**< I²C Interrupt */
ADC_IRQn = 14, /**< ADC Interrupt */
WDT_IRQn = 18, /**< Watchdog Timer Interrupt */
GPT0A_IRQn = 19, /**< GPTimer 0A Interrupt */
GPT0B_IRQn = 20, /**< GPTimer 0B Interrupt */
GPT1A_IRQn = 21, /**< GPTimer 1A Interrupt */
GPT1B_IRQn = 22, /**< GPTimer 1B Interrupt */
GPT2A_IRQn = 23, /**< GPTimer 2A Interrupt */
GPT2B_IRQn = 24, /**< GPTimer 2B Interrupt */
ADC_CMP_IRQn = 25, /**< Analog Comparator Interrupt */
RF_TX_RX_ALT_IRQn = 26, /**< RF Tx/Rx (Alternate) Interrupt */
RF_ERR_ALT_IRQn = 27, /**< RF Error (Alternate) Interrupt */
SYS_CTRL_IRQn = 28, /**< System Control Interrupt */
FLASH_CTRL_IRQn = 29, /**< Flash memory Control Interrupt */
AES_ALT_IRQn = 30, /**< AES (Alternate) Interrupt */
PKA_ALT_IRQn = 31, /**< PKA (Alternate) Interrupt */
SMT_ALT_IRQn = 32, /**< SM Timer (Alternate) Interrupt */
MACT_ALT_IRQn = 33, /**< MAC Timer (Alternate) Interrupt */
SSI1_IRQn = 34, /**< SSI1 Interrupt */
GPT3A_IRQn = 35, /**< GPTimer 3A Interrupt */
GPT3B_IRQn = 36, /**< GPTimer 3B Interrupt */
UDMA_SW_IRQn = 46, /**< µDMA Software Interrupt */
UDMA_ERR_IRQn = 47, /**< µDMA Error Interrupt */
USB_IRQn = 140, /**< USB Interrupt */
RF_TX_RX_IRQn = 141, /**< RF Tx/Rx Interrupt */
RF_ERR_IRQn = 142, /**< RF Error Interrupt */
AES_IRQn = 143, /**< AES Interrupt */
PKA_IRQn = 144, /**< PKA Interrupt */
SMT_IRQn = 145, /**< SM Timer Interrupt */
MACT_IRQn = 146 /**< MAC Timer Interrupt */
} IRQn_Type;
/** @} */
/** \name Processor and Core Peripheral Section
* @{
*/
/* Configuration of the Cortex-M3 Processor and Core Peripherals */
#define __CM3_REV 0x0200 /**< Core Revision r2p0 */
#define __MPU_PRESENT 1 /**< MPU present or not */
#define __NVIC_PRIO_BITS 3 /**< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /**< Set to 1 if different SysTick Config is used */
/** @} */
/** @} */ /* CC2538_CMSIS */
#include <core_cm3.h> /* Cortex-M3 processor and core peripherals */
#ifdef __cplusplus
}
#endif
#endif /* CC2538_CM3_H */
/**
* @}
* @}
*/

View file

@ -49,7 +49,7 @@
* Clock driver implementation for the TI cc2538
*/
#include "contiki.h"
#include "systick.h"
#include "cc2538_cm3.h"
#include "reg.h"
#include "cpu.h"
#include "dev/gptimer.h"
@ -69,12 +69,12 @@
#endif
#define PRESCALER_VALUE (SYS_CTRL_SYS_CLOCK / SYS_CTRL_1MHZ - 1)
/* Reload value for SysTick counter */
/* Period of the SysTick counter expressed as a number of ticks */
#if SYS_CTRL_SYS_CLOCK % CLOCK_SECOND
/* Too low clock speeds will lead to reduced accurracy */
#error System clock speed too slow for CLOCK_SECOND, accuracy reduced
#endif
#define RELOAD_VALUE (SYS_CTRL_SYS_CLOCK / CLOCK_SECOND - 1)
#define SYSTICK_PERIOD (SYS_CTRL_SYS_CLOCK / CLOCK_SECOND)
static volatile uint64_t rt_ticks_startup = 0, rt_ticks_epoch = 0;
/*---------------------------------------------------------------------------*/
@ -92,13 +92,7 @@ static volatile uint64_t rt_ticks_startup = 0, rt_ticks_epoch = 0;
void
clock_init(void)
{
REG(SYSTICK_STRELOAD) = RELOAD_VALUE;
/* System clock source, Enable */
REG(SYSTICK_STCTRL) |= SYSTICK_STCTRL_CLK_SRC | SYSTICK_STCTRL_ENABLE;
/* Enable the SysTick Interrupt */
REG(SYSTICK_STCTRL) |= SYSTICK_STCTRL_INTEN;
SysTick_Config(SYSTICK_PERIOD);
/*
* Remove the clock gate to enable GPT0 and then initialise it
@ -230,12 +224,12 @@ void
clock_adjust(void)
{
/* Halt the SysTick while adjusting */
REG(SYSTICK_STCTRL) &= ~SYSTICK_STCTRL_ENABLE;
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
update_ticks();
/* Re-Start the SysTick */
REG(SYSTICK_STCTRL) |= SYSTICK_STCTRL_ENABLE;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
/*---------------------------------------------------------------------------*/
/**

View file

@ -1,72 +0,0 @@
/*
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* 3. Neither the name of the copyright holder nor the names of its
* 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 HOLDER 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.
*/
/**
* \addtogroup cc2538-cpu
* @{
*
* \file
* Implementations of interrupt control on the cc2538 Cortex-M3 micro
*/
/*---------------------------------------------------------------------------*/
unsigned long __attribute__((naked))
cpu_cpsie(void)
{
unsigned long ret;
/* Read PRIMASK and enable interrupts */
__asm(" mrs r0, PRIMASK\n"
" cpsie i\n"
" bx lr\n"
: "=r" (ret));
/* The inline asm returns, we never reach here.
* We add a return statement to keep the compiler happy */
return ret;
}
/*---------------------------------------------------------------------------*/
unsigned long __attribute__((naked))
cpu_cpsid(void)
{
unsigned long ret;
/* Read PRIMASK and disable interrupts */
__asm(" mrs r0, PRIMASK\n"
" cpsid i\n"
" bx lr\n"
: "=r" (ret));
/* The inline asm returns, we never reach here.
* We add a return statement to keep the compiler happy */
return ret;
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -54,17 +54,13 @@
#ifndef CPU_H_
#define CPU_H_
/** \brief Disables all CPU interrupts */
unsigned long cpu_cpsid(void);
#include "cc2538_cm3.h"
/** \brief Enables all CPU interrupts */
unsigned long cpu_cpsie(void);
/** \brief Enables all CPU interrupts */
#define INTERRUPTS_ENABLE() cpu_cpsie()
#define INTERRUPTS_ENABLE() __enable_irq()
/** \brief Disables all CPU interrupts. */
#define INTERRUPTS_DISABLE() cpu_cpsid()
#define INTERRUPTS_DISABLE() __disable_irq()
#endif /* CPU_H_ */

View file

@ -237,8 +237,8 @@ aes_auth_crypt_start(uint32_t ctrl, uint8_t key_area, const void *iv,
if(process != NULL) {
crypto_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_AES);
nvic_interrupt_enable(NVIC_INT_AES);
NVIC_ClearPendingIRQ(AES_IRQn);
NVIC_EnableIRQ(AES_IRQn);
}
if(data_len != 0) {
@ -282,7 +282,7 @@ aes_auth_crypt_get_result(void *iv, void *tag)
AES_CTRL_INT_CLR_KEY_ST_WR_ERR |
AES_CTRL_INT_CLR_KEY_ST_RD_ERR;
nvic_interrupt_disable(NVIC_INT_AES);
NVIC_DisableIRQ(AES_IRQn);
crypto_register_process_notification(NULL);
/* Disable the master control / DMA clock */

View file

@ -130,8 +130,8 @@ bignum_mod_start(const uint32_t *number,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -158,7 +158,7 @@ bignum_mod_get_result(uint32_t *buffer,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
/* Get the MSW register value. */
@ -238,8 +238,8 @@ bignum_cmp_start(const uint32_t *number1,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -257,7 +257,7 @@ bignum_cmp_get_result(void)
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
/* Check the compare register. */
@ -346,8 +346,8 @@ bignum_inv_mod_start(const uint32_t *number,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -374,7 +374,7 @@ bignum_inv_mod_get_result(uint32_t *buffer,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
/* Get the MSW register value. */
@ -469,8 +469,8 @@ bignum_mul_start(const uint32_t *multiplicand,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -498,7 +498,7 @@ bignum_mul_get_result(uint32_t *buffer,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
/* Get the MSW register value. */
@ -594,8 +594,8 @@ bignum_add_start(const uint32_t *number1,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -623,7 +623,7 @@ bignum_add_get_result(uint32_t *buffer,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
/* Get the MSW register value. */
@ -720,8 +720,8 @@ bignum_subtract_start(const uint32_t *number1,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -749,7 +749,7 @@ bignum_subtract_get_result(uint32_t *buffer,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
/* Get the MSW register value. */
@ -864,8 +864,8 @@ bignum_exp_mod_start(const uint32_t *number,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -892,7 +892,7 @@ bignum_exp_mod_get_result(uint32_t *buffer,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
/* Get the MSW register value. */
@ -1000,8 +1000,8 @@ bignum_divide_start(const uint32_t *dividend,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -1029,7 +1029,7 @@ bignum_divide_get_result(uint32_t *buffer,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
/* Get the MSW register value. */

View file

@ -345,10 +345,10 @@ set_poll_mode(uint8_t enable)
mac_timer_init();
REG(RFCORE_XREG_RFIRQM0) &= ~RFCORE_XREG_RFIRQM0_FIFOP; /* mask out FIFOP interrupt source */
REG(RFCORE_SFR_RFIRQF0) &= ~RFCORE_SFR_RFIRQF0_FIFOP; /* clear pending FIFOP interrupt */
nvic_interrupt_disable(NVIC_INT_RF_RXTX); /* disable RF interrupts */
NVIC_DisableIRQ(RF_TX_RX_IRQn); /* disable RF interrupts */
} else {
REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP; /* enable FIFOP interrupt source */
nvic_interrupt_enable(NVIC_INT_RF_RXTX); /* enable RF interrupts */
NVIC_EnableIRQ(RF_TX_RX_IRQn); /* enable RF interrupts */
}
}
/*---------------------------------------------------------------------------*/
@ -516,7 +516,7 @@ init(void)
/* Acknowledge all RF Error interrupts */
REG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM;
nvic_interrupt_enable(NVIC_INT_RF_ERR);
NVIC_EnableIRQ(RF_ERR_IRQn);
if(CC2538_RF_CONF_TX_USE_DMA) {
/* Disable peripheral triggers for the channel */

View file

@ -61,8 +61,8 @@ crypto_isr(void)
{
ENERGEST_ON(ENERGEST_TYPE_IRQ);
nvic_interrupt_unpend(NVIC_INT_AES);
nvic_interrupt_disable(NVIC_INT_AES);
NVIC_ClearPendingIRQ(AES_IRQn);
NVIC_DisableIRQ(AES_IRQn);
if(notification_process != NULL) {
process_poll((struct process *)notification_process);

View file

@ -152,8 +152,8 @@ ecc_mul_start(uint32_t *scalar, ec_point_t *ec_point,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -181,7 +181,7 @@ ecc_mul_get_result(ec_point_t *ec_point,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
if(REG(PKA_SHIFT) == 0x00000000) {
@ -319,8 +319,8 @@ ecc_mul_gen_pt_start(uint32_t *scalar, ecc_curve_info_t *curve,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -349,7 +349,7 @@ ecc_mul_gen_pt_get_result(ec_point_t *ec_point,
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
if(REG(PKA_SHIFT) == 0x00000000) {
@ -492,8 +492,8 @@ ecc_add_start(ec_point_t *ec_point1, ec_point_t *ec_point2,
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_EnableIRQ(PKA_IRQn);
}
return PKA_STATUS_SUCCESS;
@ -519,7 +519,7 @@ ecc_add_get_result(ec_point_t *ec_point, uint32_t result_vector)
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_DisableIRQ(PKA_IRQn);
pka_register_process_notification(NULL);
if(REG(PKA_SHIFT) == 0x00000000) {

View file

@ -1,68 +0,0 @@
/*
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* 3. Neither the name of the copyright holder nor the names of its
* 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 HOLDER 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.
*/
/**
* \addtogroup cc2538
* @{
*
* \defgroup cc2538-mpu cc2538 Memory Protection Unit
*
* Driver for the cc2538 Memory Protection Unit
* @{
*
* \file
* Header file for the ARM Memory Protection Unit
*/
#ifndef MPU_H_
#define MPU_H_
#define MPU_MPU_TYPE 0xE000ED90 /**< MPU Type */
#define MPU_MPU_CTRL 0xE000ED94 /**< MPU Control */
#define MPU_MPU_NUMBER 0xE000ED98 /**< MPU Region Number */
#define MPU_MPU_BASE 0xE000ED9C /**< MPU Region Base Address */
#define MPU_MPU_ATTR 0xE000EDA0 /**< MPU Region Attribute and Size */
#define MPU_MPU_BASE1 0xE000EDA4 /**< MPU Region Base Address Alias 1 */
#define MPU_MPU_ATTR1 0xE000EDA8 /**< MPU Region Attribute and Size Alias 1 */
#define MPU_MPU_BASE2 0xE000EDAC /**< MPU Region Base Address Alias 2 */
#define MPU_MPU_ATTR2 0xE000EDB0 /**< MPU Region Attribute and Size Alias 2*/
#define MPU_MPU_BASE3 0xE000EDB4 /**< MPU Region Base Address Alias 3 */
#define MPU_MPU_ATTR3 0xE000EDB8 /**< MPU Region Attribute and Size Alias 3*/
#define MPU_DBG_CTRL 0xE000EDF0 /**< Debug Control and Status Reg */
#define MPU_DBG_XFER 0xE000EDF4 /**< Debug Core Reg. Transfer Select */
#define MPU_DBG_DATA 0xE000EDF8 /**< Debug Core Register Data */
#define MPU_DBG_INT 0xE000EDFC /**< Debug Reset Interrupt Control */
#define MPU_SW_TRIG 0xE000EF00 /**< Software Trigger Interrupt */
#endif /* MPU_H_ */
/**
* @}
* @}
*/

View file

@ -38,74 +38,12 @@
*/
#include "contiki.h"
#include "dev/nvic.h"
#include "dev/scb.h"
#include "reg.h"
#include <stdint.h>
static uint32_t *interrupt_enable;
static uint32_t *interrupt_disable;
static uint32_t *interrupt_pend;
static uint32_t *interrupt_unpend;
#include "cc2538_cm3.h"
/*---------------------------------------------------------------------------*/
void
nvic_init()
{
interrupt_enable = (uint32_t *)NVIC_EN0;
interrupt_disable = (uint32_t *)NVIC_DIS0;
interrupt_pend = (uint32_t *)NVIC_PEND0;
interrupt_unpend = (uint32_t *)NVIC_UNPEND0;
/* Provide our interrupt table to the NVIC */
REG(SCB_VTABLE) = NVIC_VTABLE_ADDRESS;
}
/*---------------------------------------------------------------------------*/
void
nvic_interrupt_enable(uint32_t intr)
{
/* Writes of 0 are ignored, which is why we can simply use = */
interrupt_enable[intr >> 5] = 1 << (intr & 0x1F);
}
/*---------------------------------------------------------------------------*/
void
nvic_interrupt_disable(uint32_t intr)
{
/* Writes of 0 are ignored, which is why we can simply use = */
interrupt_disable[intr >> 5] = 1 << (intr & 0x1F);
}
/*---------------------------------------------------------------------------*/
void
nvic_interrupt_en_restore(uint32_t intr, uint8_t v)
{
if(v != 1) {
return;
}
interrupt_enable[intr >> 5] = 1 << (intr & 0x1F);
}
/*---------------------------------------------------------------------------*/
uint8_t
nvic_interrupt_en_save(uint32_t intr)
{
uint8_t rv = ((interrupt_enable[intr >> 5] & (1 << (intr & 0x1F)))
> NVIC_INTERRUPT_DISABLED);
nvic_interrupt_disable(intr);
return rv;
}
/*---------------------------------------------------------------------------*/
void
nvic_interrupt_pend(uint32_t intr)
{
/* Writes of 0 are ignored, which is why we can simply use = */
interrupt_pend[intr >> 5] = 1 << (intr & 0x1F);
}
/*---------------------------------------------------------------------------*/
void
nvic_interrupt_unpend(uint32_t intr)
{
/* Writes of 0 are ignored, which is why we can simply use = */
interrupt_unpend[intr >> 5] = 1 << (intr & 0x1F);
SCB->VTOR = NVIC_VTABLE_ADDRESS;
}
/** @} */

View file

@ -43,14 +43,13 @@
#ifndef NVIC_H_
#define NVIC_H_
#include "cc2538_cm3.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \name NVIC Constants and Configuration
* @{
*/
#define NVIC_INTERRUPT_ENABLED 0x00000001
#define NVIC_INTERRUPT_DISABLED 0x00000000
#ifdef NVIC_CONF_VTABLE_ADDRESS
#define NVIC_VTABLE_ADDRESS NVIC_CONF_VTABLE_ADDRESS
#else
@ -59,183 +58,9 @@ extern void(*const vectors[])(void);
#endif
/** @} */
/*---------------------------------------------------------------------------*/
/** \name NVIC Interrupt assignments
* @{
*/
#define NVIC_INT_GPIO_PORT_A 0 /**< GPIO port A */
#define NVIC_INT_GPIO_PORT_B 1 /**< GPIO port B */
#define NVIC_INT_GPIO_PORT_C 2 /**< GPIO port C */
#define NVIC_INT_GPIO_PORT_D 3 /**< GPIO port D */
#define NVIC_INT_UART0 5 /**< UART0 */
#define NVIC_INT_UART1 6 /**< UART1 */
#define NVIC_INT_SSI0 7 /**< SSI0 */
#define NVIC_INT_I2C 8 /**< I2C */
#define NVIC_INT_ADC 14 /**< ADC */
#define NVIC_INT_WDT 18 /**< Watchdog Timer */
#define NVIC_INT_GPTIMER_0A 19 /**< GPTimer 0A */
#define NVIC_INT_GPTIMER_0B 20 /**< GPTimer 0B */
#define NVIC_INT_GPTIMER_1A 21 /**< GPTimer 1A */
#define NVIC_INT_GPTIMER_1B 22 /**< GPTimer 1B */
#define NVIC_INT_GPTIMER_2A 23 /**< GPTimer 2A */
#define NVIC_INT_GPTIMER_2B 24 /**< GPTimer 2B */
#define NVIC_INT_ADC_CMP 25 /**< Analog Comparator */
#define NVIC_INT_RF_RXTX_ALT 26 /**< RF TX/RX (Alternate) */
#define NVIC_INT_RF_ERR_ALT 27 /**< RF Error (Alternate) */
#define NVIC_INT_SYS_CTRL 28 /**< System Control */
#define NVIC_INT_FLASH_CTRL 29 /**< Flash memory control */
#define NVIC_INT_AES_ALT 30 /**< AES (Alternate) */
#define NVIC_INT_PKA_ALT 31 /**< PKA (Alternate) */
#define NVIC_INT_SM_TIMER_ALT 32 /**< SM Timer (Alternate) */
#define NVIC_INT_MAC_TIMER_ALT 33 /**< MAC Timer (Alternate) */
#define NVIC_INT_SSI1 34 /**< SSI1 */
#define NVIC_INT_GPTIMER_3A 35 /**< GPTimer 3A */
#define NVIC_INT_GPTIMER_3B 36 /**< GPTimer 3B */
#define NVIC_INT_UDMA 46 /**< uDMA software */
#define NVIC_INT_UDMA_ERR 47 /**< uDMA error */
#define NVIC_INT_USB 140 /**< USB */
#define NVIC_INT_RF_RXTX 141 /**< RF Core Rx/Tx */
#define NVIC_INT_RF_ERR 142 /**< RF Core Error */
#define NVIC_INT_AES 143 /**< AES */
#define NVIC_INT_PKA 144 /**< PKA */
#define NVIC_INT_SM_TIMER 145 /**< SM Timer */
#define NVIC_INT_MACTIMER 146 /**< MAC Timer */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name NVIC Register Declarations
* @{
*/
#define NVIC_EN0 0xE000E100 /**< Interrupt 0-31 Set Enable */
#define NVIC_EN1 0xE000E104 /**< Interrupt 32-54 Set Enable */
#define NVIC_EN2 0xE000E108 /**< Interrupt 64-95 Set Enable */
#define NVIC_EN3 0xE000E10C /**< Interrupt 96-127 Set Enable */
#define NVIC_EN4 0xE000E110 /**< Interrupt 128-131 Set Enable */
#define NVIC_DIS0 0xE000E180 /**< Interrupt 0-31 Clear Enable */
#define NVIC_DIS1 0xE000E184 /**< Interrupt 32-54 Clear Enable */
#define NVIC_DIS2 0xE000E188 /**< Interrupt 64-95 Clear Enable */
#define NVIC_DIS3 0xE000E18C /**< Interrupt 96-127 Clear Enable */
#define NVIC_DIS4 0xE000E190 /**< Interrupt 128-131 Clear Enable */
#define NVIC_PEND0 0xE000E200 /**< Interrupt 0-31 Set Pending */
#define NVIC_PEND1 0xE000E204 /**< Interrupt 32-54 Set Pending */
#define NVIC_PEND2 0xE000E208 /**< Interrupt 64-95 Set Pending */
#define NVIC_PEND3 0xE000E20C /**< Interrupt 96-127 Set Pending */
#define NVIC_PEND4 0xE000E210 /**< Interrupt 128-131 Set Pending */
#define NVIC_UNPEND0 0xE000E280 /**< Interrupt 0-31 Clear Pending */
#define NVIC_UNPEND1 0xE000E284 /**< Interrupt 32-54 Clear Pending */
#define NVIC_UNPEND2 0xE000E288 /**< Interrupt 64-95 Clear Pending */
#define NVIC_UNPEND3 0xE000E28C /**< Interrupt 96-127 Clear Pending */
#define NVIC_UNPEND4 0xE000E290 /**< Interrupt 128-131 Clear Pending */
#define NVIC_ACTIVE0 0xE000E300 /**< Interrupt 0-31 Active Bit */
#define NVIC_ACTIVE1 0xE000E304 /**< Interrupt 32-54 Active Bit */
#define NVIC_ACTIVE2 0xE000E308 /**< Interrupt 64-95 Active Bit */
#define NVIC_ACTIVE3 0xE000E30C /**< Interrupt 96-127 Active Bit */
#define NVIC_ACTIVE4 0xE000E310 /**< Interrupt 128-131 Active Bit */
#define NVIC_PRI0 0xE000E400 /**< Interrupt 0-3 Priority */
#define NVIC_PRI1 0xE000E404 /**< Interrupt 4-7 Priority */
#define NVIC_PRI2 0xE000E408 /**< Interrupt 8-11 Priority */
#define NVIC_PRI3 0xE000E40C /**< Interrupt 12-15 Priority */
#define NVIC_PRI4 0xE000E410 /**< Interrupt 16-19 Priority */
#define NVIC_PRI5 0xE000E414 /**< Interrupt 20-23 Priority */
#define NVIC_PRI6 0xE000E418 /**< Interrupt 24-27 Priority */
#define NVIC_PRI7 0xE000E41C /**< Interrupt 28-31 Priority */
#define NVIC_PRI8 0xE000E420 /**< Interrupt 32-35 Priority */
#define NVIC_PRI9 0xE000E424 /**< Interrupt 36-39 Priority */
#define NVIC_PRI10 0xE000E428 /**< Interrupt 40-43 Priority */
#define NVIC_PRI11 0xE000E42C /**< Interrupt 44-47 Priority */
#define NVIC_PRI12 0xE000E430 /**< Interrupt 48-51 Priority */
#define NVIC_PRI13 0xE000E434 /**< Interrupt 52-53 Priority */
#define NVIC_PRI14 0xE000E438 /**< Interrupt 56-59 Priority */
#define NVIC_PRI15 0xE000E43C /**< Interrupt 60-63 Priority */
#define NVIC_PRI16 0xE000E440 /**< Interrupt 64-67 Priority */
#define NVIC_PRI17 0xE000E444 /**< Interrupt 68-71 Priority */
#define NVIC_PRI18 0xE000E448 /**< Interrupt 72-75 Priority */
#define NVIC_PRI19 0xE000E44C /**< Interrupt 76-79 Priority */
#define NVIC_PRI20 0xE000E450 /**< Interrupt 80-83 Priority */
#define NVIC_PRI21 0xE000E454 /**< Interrupt 84-87 Priority */
#define NVIC_PRI22 0xE000E458 /**< Interrupt 88-91 Priority */
#define NVIC_PRI23 0xE000E45C /**< Interrupt 92-95 Priority */
#define NVIC_PRI24 0xE000E460 /**< Interrupt 96-99 Priority */
#define NVIC_PRI25 0xE000E464 /**< Interrupt 100-103 Priority */
#define NVIC_PRI26 0xE000E468 /**< Interrupt 104-107 Priority */
#define NVIC_PRI27 0xE000E46C /**< Interrupt 108-111 Priority */
#define NVIC_PRI28 0xE000E470 /**< Interrupt 112-115 Priority */
#define NVIC_PRI29 0xE000E474 /**< Interrupt 116-119 Priority */
#define NVIC_PRI30 0xE000E478 /**< Interrupt 120-123 Priority */
#define NVIC_PRI31 0xE000E47C /**< Interrupt 124-127 Priority */
#define NVIC_PRI32 0xE000E480 /**< Interrupt 128-131 Priority */
#define NVIC_PRI33 0xE000E480 /**< Interrupt 132-135 Priority */
#define NVIC_PRI34 0xE000E484 /**< Interrupt 136-139 Priority */
#define NVIC_PRI35 0xE000E488 /**< Interrupt 140-143 Priority */
#define NVIC_PRI36 0xE000E48c /**< Interrupt 144-147 Priority */
/** @} */
/*---------------------------------------------------------------------------*/
/** \brief Initialises the NVIC driver */
void nvic_init();
/**
* \brief Enables interrupt intr
* \param intr The interrupt number (NOT the vector number). For example,
* GPIO Port A interrupt is 0, not 16.
*
* Possible values for the \e intr param are defined as NVIC_INT_xyz. For
* instance, to enable the GPIO Port A interrupt, pass NVIC_INT_GPIO_PORT_A
*/
void nvic_interrupt_enable(uint32_t intr);
/**
* \brief Disables interrupt intr
* \param intr The interrupt number (NOT the vector number). For example,
* GPIO Port A interrupt is 0, not 16.
*
* Possible values for the \e intr param are defined as NVIC_INT_xyz. For
* instance, to disable the GPIO Port A interrupt, pass NVIC_INT_GPIO_PORT_A
*/
void nvic_interrupt_disable(uint32_t intr);
/**
* \brief Enables interrupt intr if v > 0
* \param intr The interrupt number (NOT the vector number). For example,
* GPIO Port A interrupt is 0, not 16.
* \param v 0: No effect, 1: Enables the interrupt
*
* This function is useful to restore an interrupt to a state previously
* saved by nvic_interrupt_en_save. Thus, if when nvic_interrupt_en_save was
* called the interrupt was enabled, this function will re-enabled it.
* Possible values for the \e intr param are defined as NVIC_INT_xyz. For
* instance, to disable the GPIO Port A interrupt, pass NVIC_INT_GPIO_PORT_A
*/
void nvic_interrupt_en_restore(uint32_t intr, uint8_t v);
/**
* \brief Checks the interrupt enabled status for intr
* \param intr The interrupt number (NOT the vector number). For example,
* GPIO Port A interrupt is 0, not 16.
* \return 1: Enabled, 0: Disabled
*
* Possible values for the \e intr param are defined as NVIC_INT_xyz. For
* instance, to disable the GPIO Port A interrupt, pass NVIC_INT_GPIO_PORT_A
*/
uint8_t nvic_interrupt_en_save(uint32_t intr);
/**
* \brief Sets intr to pending
* \param intr The interrupt number (NOT the vector number). For example,
* GPIO Port A interrupt is 0, not 16.
*
* Possible values for the \e intr param are defined as NVIC_INT_xyz. For
* instance, to enable the GPIO Port A interrupt, pass NVIC_INT_GPIO_PORT_A
*/
void nvic_interrupt_pend(uint32_t intr);
/**
* \brief Sets intr to no longer pending
* \param intr The interrupt number (NOT the vector number). For example,
* GPIO Port A interrupt is 0, not 16.
*
* Possible values for the \e intr param are defined as NVIC_INT_xyz. For
* instance, to disable the GPIO Port A interrupt, pass NVIC_INT_GPIO_PORT_A
*/
void nvic_interrupt_unpend(uint32_t intr);
#endif /* NVIC_H_ */
/**

View file

@ -64,8 +64,8 @@ pka_isr(void)
{
ENERGEST_ON(ENERGEST_TYPE_IRQ);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_disable(NVIC_INT_PKA);
NVIC_ClearPendingIRQ(PKA_IRQn);
NVIC_DisableIRQ(PKA_IRQn);
if(notification_process != NULL) {
process_poll((struct process *)notification_process);

View file

@ -1,83 +0,0 @@
/*
* Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* 3. Neither the name of the copyright holder nor the names of its
* 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 HOLDER 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.
*/
/**
* \addtogroup cc2538
* @{
*
* \defgroup cc2538-scb cc2538 System Control Block (SCB)
*
* Offsets and bit definitions for SCB registers
* @{
*
* \file
* Header file for the System Control Block (SCB)
*/
#ifndef SCB_H_
#define SCB_H_
#define SCB_CPUID 0xE000ED00 /**< CPU ID Base */
#define SCB_INTCTRL 0xE000ED04 /**< Interrupt Control and State */
#define SCB_VTABLE 0xE000ED08 /**< Vector Table Offset */
#define SCB_APINT 0xE000ED0C /**< Application Interrupt and Reset Control */
#define SCB_SYSCTRL 0xE000ED10 /**< System Control */
#define SCB_CFGCTRL 0xE000ED14 /**< Configuration and Control */
#define SCB_SYSPRI1 0xE000ED18 /**< System Handler Priority 1 */
#define SCB_SYSPRI2 0xE000ED1C /**< System Handler Priority 2 */
#define SCB_SYSPRI3 0xE000ED20 /**< System Handler Priority 3 */
#define SCB_SYSHNDCTRL 0xE000ED24 /**< System Handler Control and State */
#define SCB_FAULTSTAT 0xE000ED28 /**< Configurable Fault Status */
#define SCB_HFAULTSTAT 0xE000ED2C /**< Hard Fault Status */
#define SCB_DEBUG_STAT 0xE000ED30 /**< Debug Status Register */
#define SCB_MMADDR 0xE000ED34 /**< Memory Management Fault Address */
#define SCB_FAULT_ADDR 0xE000ED38 /**< Bus Fault Address */
/*---------------------------------------------------------------------------*/
/** \name VTABLE register bits
* @{
*/
#define SCB_VTABLE_BASE 0x20000000 /**< Vector Table Base */
#define SCB_VTABLE_OFFSET_M 0x1FFFFE00 /**< Vector Table Offset */
/** @} */
/*---------------------------------------------------------------------------*/
/** \name SCB_SYSCTRL register bits
* @{
*/
#define SCB_SYSCTRL_SEVONPEND 0x00000010 /**< Wake up on pending */
#define SCB_SYSCTRL_SLEEPDEEP 0x00000004 /**< Deep sleep enable */
#define SCB_SYSCTRL_SLEEPEXIT 0x00000002 /**< Sleep on ISR exit */
/** @} */
/*---------------------------------------------------------------------------*/
#endif /* SCB_H_ */
/**
* @}
* @}
*/

View file

@ -1,53 +0,0 @@
/*
* Copyright (c) 2012, Texas Instruments Incorporated - http:/www.ti.com/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* 3. Neither the name of the copyright holder nor the names of its
* 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 HOLDER 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.
*/
/**
* \file
* Header for with definitions related to the cc2538 SysTick
*/
/*---------------------------------------------------------------------------*/
#ifndef SYSTICK_H_
#define SYSTICK_H_
/*---------------------------------------------------------------------------*/
/* SysTick Register Definitions */
#define SYSTICK_STCTRL 0xE000E010 /* Control and Status */
#define SYSTICK_STRELOAD 0xE000E014 /* Reload Value */
#define SYSTICK_STCURRENT 0xE000E018 /* Current Value */
#define SYSTICK_STCAL 0xE000E01C /* SysTick Calibration */
/*---------------------------------------------------------------------------*/
/* Bit Definitions for the STCTRL Register */
#define SYSTICK_STCTRL_COUNT 0x00010000 /* Count Flag */
#define SYSTICK_STCTRL_CLK_SRC 0x00000004 /* Clock Source */
#define SYSTICK_STCTRL_INTEN 0x00000002 /* Interrupt Enable */
#define SYSTICK_STCTRL_ENABLE 0x00000001 /* Enable */
#endif /* SYSTICK_H_ */
/** @} */

View file

@ -181,7 +181,7 @@ static const uart_regs_t uart_regs[UART_INSTANCE_COUNT] = {
.tx = {UART0_TX_PORT, UART0_TX_PIN},
.cts = {-1, -1},
.rts = {-1, -1},
.nvic_int = NVIC_INT_UART0
.nvic_int = UART0_IRQn
}, {
.sys_ctrl_rcgcuart_uart = SYS_CTRL_RCGCUART_UART1,
.sys_ctrl_scgcuart_uart = SYS_CTRL_SCGCUART_UART1,
@ -195,7 +195,7 @@ static const uart_regs_t uart_regs[UART_INSTANCE_COUNT] = {
.tx = {UART1_TX_PORT, UART1_TX_PIN},
.cts = {UART1_CTS_PORT, UART1_CTS_PIN},
.rts = {UART1_RTS_PORT, UART1_RTS_PIN},
.nvic_int = NVIC_INT_UART1
.nvic_int = UART1_IRQn
}
};
static int (* input_handler[UART_INSTANCE_COUNT])(unsigned char c);
@ -328,7 +328,7 @@ uart_init(uint8_t uart)
REG(regs->base + UART_CTL) |= UART_CTL_UARTEN;
/* Enable UART0 Interrupts */
nvic_interrupt_enable(regs->nvic_int);
NVIC_EnableIRQ(regs->nvic_int);
}
/*---------------------------------------------------------------------------*/
void

View file

@ -62,8 +62,8 @@ udma_init()
REG(UDMA_CTLBASE) = (uint32_t)(&channel_config);
nvic_interrupt_enable(NVIC_INT_UDMA);
nvic_interrupt_enable(NVIC_INT_UDMA_ERR);
NVIC_EnableIRQ(UDMA_SW_IRQn);
NVIC_EnableIRQ(UDMA_ERR_IRQn);
}
/*---------------------------------------------------------------------------*/
void

View file

@ -39,10 +39,10 @@
#include "sys/energest.h"
#include "sys/process.h"
#include "dev/sys-ctrl.h"
#include "dev/scb.h"
#include "dev/rfcore-xreg.h"
#include "rtimer-arch.h"
#include "lpm.h"
#include "cc2538_cm3.h"
#include "reg.h"
#include <stdbool.h>
@ -379,7 +379,7 @@ lpm_init()
* By default, we will enter PM0 unless lpm_enter() decides otherwise
*/
REG(SYS_CTRL_PMCTL) = SYS_CTRL_PMCTL_PM0;
REG(SCB_SYSCTRL) |= SCB_SYSCTRL_SLEEPDEEP;
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
max_pm = LPM_CONF_MAX_PM;

View file

@ -1,48 +0,0 @@
/*
* Copyright (c) 2010, Loughborough University - Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
/*
* \file
* Stub header file for multi-threading. It doesn't do anything, it
* just exists so that mt.c can compile cleanly.
*
* This is based on the original mtarch.h for z80 by Takahide Matsutsuka
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef MTARCH_H_
#define MTARCH_H_
struct mtarch_thread {
unsigned char *sp;
};
#endif /* MTARCH_H_ */

View file

@ -99,7 +99,7 @@ rtimer_arch_schedule(rtimer_clock_t t)
/* Store the value. The LPM module will query us for it */
next_trigger = t;
nvic_interrupt_enable(NVIC_INT_SM_TIMER);
NVIC_EnableIRQ(SMT_IRQn);
}
/*---------------------------------------------------------------------------*/
rtimer_clock_t
@ -147,8 +147,8 @@ rtimer_isr()
next_trigger = 0;
nvic_interrupt_unpend(NVIC_INT_SM_TIMER);
nvic_interrupt_disable(NVIC_INT_SM_TIMER);
NVIC_ClearPendingIRQ(SMT_IRQn);
NVIC_DisableIRQ(SMT_IRQn);
rtimer_run_next();

View file

@ -52,6 +52,8 @@ void nmi_handler(void);
void default_handler(void);
/* System Handler and ISR prototypes implemented elsewhere */
void svcall_handler(void); /* See mtarch.c */
void pendsv_handler(void); /* See mtarch.c */
void clock_isr(void); /* SysTick Handler */
void gpio_port_a_isr(void);
void gpio_port_b_isr(void);
@ -119,10 +121,10 @@ void(*const vectors[])(void) =
0, /* 8 Reserved */
0, /* 9 Reserved */
0, /* 10 Reserved */
default_handler, /* 11 SVCall handler */
svcall_handler, /* 11 SVCall handler */
default_handler, /* 12 Debug monitor handler */
0, /* 13 Reserved */
default_handler, /* 14 The PendSV handler */
pendsv_handler, /* 14 The PendSV handler */
clock_isr, /* 15 The SysTick handler */
gpio_port_a_isr, /* 16 GPIO Port A */
gpio_port_b_isr, /* 17 GPIO Port B */

View file

@ -167,6 +167,24 @@ static void in_ep_interrupt_handler(uint8_t ep_hw);
static void out_ep_interrupt_handler(uint8_t ep_hw);
static void ep0_interrupt_handler(void);
/*---------------------------------------------------------------------------*/
static uint8_t
disable_irq(void)
{
uint8_t enabled = NVIC_IsIRQEnabled(USB_IRQn);
if(enabled) {
NVIC_DisableIRQ(USB_IRQn);
}
return enabled;
}
/*---------------------------------------------------------------------------*/
static void
restore_irq(uint8_t enabled)
{
if(enabled) {
NVIC_EnableIRQ(USB_IRQn);
}
}
/*---------------------------------------------------------------------------*/
static void
notify_process(unsigned int e)
{
@ -205,12 +223,12 @@ usb_arch_get_global_events(void)
uint8_t flag;
volatile unsigned int e;
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
e = events;
events = 0;
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
return e;
}
@ -222,12 +240,12 @@ usb_get_ep_events(uint8_t addr)
uint8_t flag;
usb_endpoint_t *ep = EP_STRUCT(addr);
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
e = ep->events;
ep->events = 0;
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
return e;
}
@ -360,7 +378,7 @@ usb_arch_setup(void)
udma_channel_mask_set(USB_ARCH_CONF_TX_DMA_CHAN);
}
nvic_interrupt_enable(NVIC_INT_USB);
NVIC_EnableIRQ(USB_IRQn);
}
/*---------------------------------------------------------------------------*/
void
@ -381,7 +399,7 @@ usb_submit_recv_buffer(uint8_t addr, usb_buffer *buffer)
return;
}
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
tailp = &ep->buffer;
while(*tailp) {
@ -404,7 +422,7 @@ usb_submit_recv_buffer(uint8_t addr, usb_buffer *buffer)
}
}
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
}
/*---------------------------------------------------------------------------*/
void
@ -419,7 +437,7 @@ usb_submit_xmit_buffer(uint8_t addr, usb_buffer *buffer)
return;
}
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
if(EP_HW_NUM(addr) == 0) {
if(buffer->data == NULL) {
@ -429,7 +447,7 @@ usb_submit_xmit_buffer(uint8_t addr, usb_buffer *buffer)
REG(USB_INDEX) = 0;
REG(USB_CS0) = USB_CS0_CLR_OUTPKT_RDY | USB_CS0_DATA_END;
notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
return;
} else {
/* Release the HW FIFO */
@ -455,7 +473,7 @@ usb_submit_xmit_buffer(uint8_t addr, usb_buffer *buffer)
res = ep0_tx();
}
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
if(res & USB_WRITE_NOTIFY) {
notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
@ -520,7 +538,7 @@ ep_setup(uint8_t addr)
ep->events = 0;
ep->xfer_size = ep_xfer_size[ei];
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
/* Select endpoint register */
REG(USB_INDEX) = ei;
@ -536,7 +554,7 @@ ep_setup(uint8_t addr)
}
}
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
}
/*---------------------------------------------------------------------------*/
void
@ -616,7 +634,7 @@ usb_arch_disable_endpoint(uint8_t addr)
ep->flags &= ~USB_EP_FLAGS_ENABLED;
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
REG(USB_INDEX) = ei;
if(ei == 0) {
@ -628,7 +646,7 @@ usb_arch_disable_endpoint(uint8_t addr)
out_ep_dis(addr);
}
}
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
}
/*---------------------------------------------------------------------------*/
void
@ -638,11 +656,11 @@ usb_arch_discard_all_buffers(uint8_t addr)
uint8_t flag;
volatile usb_endpoint_t *ep = EP_STRUCT(addr);
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
buffer = ep->buffer;
ep->buffer = NULL;
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
while(buffer) {
buffer->flags &= ~USB_BUFFER_SUBMITTED;
@ -689,11 +707,11 @@ usb_arch_control_stall(uint8_t addr)
return;
}
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
set_stall(addr, 1);
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
}
/*---------------------------------------------------------------------------*/
void
@ -711,7 +729,7 @@ usb_arch_halt_endpoint(uint8_t addr, int halt)
return;
}
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
if(halt) {
ep->halted = 0x1;
@ -732,7 +750,7 @@ usb_arch_halt_endpoint(uint8_t addr, int halt)
}
}
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
}
/*---------------------------------------------------------------------------*/
void
@ -767,7 +785,7 @@ usb_arch_send_pending(uint8_t addr)
uint8_t ret;
uint8_t ei = EP_INDEX(addr);
flag = nvic_interrupt_en_save(NVIC_INT_USB);
flag = disable_irq();
REG(USB_INDEX) = ei;
if(ei == 0) {
@ -776,7 +794,7 @@ usb_arch_send_pending(uint8_t addr)
ret = REG(USB_CSIL) & USB_CSIL_INPKT_RDY;
}
nvic_interrupt_en_restore(NVIC_INT_USB, flag);
restore_irq(flag);
return ret;
}

View file

@ -50,7 +50,6 @@
#include "dev/watchdog.h"
#include "dev/sys-ctrl.h"
#include "pwm.h"
#include "systick.h"
#include "lpm.h"
#include "dev/ioc.h"
#include <stdio.h>

View file

@ -152,7 +152,7 @@ PROCESS_THREAD(cc2538_demo_process, ev, data)
} else if(data == &button_left_sensor || data == &button_right_sensor) {
leds_toggle(LEDS_BUTTON);
} else if(data == &button_down_sensor) {
cpu_cpsid();
INTERRUPTS_DISABLE();
leds_on(LEDS_REBOOT);
watchdog_reboot();
} else if(data == &button_up_sensor) {

View file

@ -48,7 +48,7 @@
*/
#define MOTION_SENSOR_PORT GPIO_A_NUM
#define MOTION_SENSOR_PIN 5
#define MOTION_SENSOR_VECTOR NVIC_INT_GPIO_PORT_A
#define MOTION_SENSOR_VECTOR GPIO_A_IRQn
#endif /* PROJECT_CONF_H_ */

View file

@ -46,7 +46,6 @@
#include "dev/adc.h"
#include "dev/leds.h"
#include "dev/sys-ctrl.h"
#include "dev/scb.h"
#include "dev/nvic.h"
#include "dev/uart.h"
#include "dev/watchdog.h"

View file

@ -141,27 +141,27 @@
/** BUTTON_SELECT -> PA3 */
#define BUTTON_SELECT_PORT GPIO_A_NUM
#define BUTTON_SELECT_PIN 3
#define BUTTON_SELECT_VECTOR NVIC_INT_GPIO_PORT_A
#define BUTTON_SELECT_VECTOR GPIO_A_IRQn
/** BUTTON_LEFT -> PC4 */
#define BUTTON_LEFT_PORT GPIO_C_NUM
#define BUTTON_LEFT_PIN 4
#define BUTTON_LEFT_VECTOR NVIC_INT_GPIO_PORT_C
#define BUTTON_LEFT_VECTOR GPIO_C_IRQn
/** BUTTON_RIGHT -> PC5 */
#define BUTTON_RIGHT_PORT GPIO_C_NUM
#define BUTTON_RIGHT_PIN 5
#define BUTTON_RIGHT_VECTOR NVIC_INT_GPIO_PORT_C
#define BUTTON_RIGHT_VECTOR GPIO_C_IRQn
/** BUTTON_UP -> PC6 */
#define BUTTON_UP_PORT GPIO_C_NUM
#define BUTTON_UP_PIN 6
#define BUTTON_UP_VECTOR NVIC_INT_GPIO_PORT_C
#define BUTTON_UP_VECTOR GPIO_C_IRQn
/** BUTTON_DOWN -> PC7 */
#define BUTTON_DOWN_PORT GPIO_C_NUM
#define BUTTON_DOWN_PIN 7
#define BUTTON_DOWN_VECTOR NVIC_INT_GPIO_PORT_C
#define BUTTON_DOWN_VECTOR GPIO_C_IRQn
/* Notify various examples that we have Buttons */
#define PLATFORM_HAS_BUTTON 1

View file

@ -135,7 +135,7 @@ config_select(int type, int value)
ioc_set_over(BUTTON_SELECT_PORT, BUTTON_SELECT_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(BUTTON_SELECT_VECTOR);
NVIC_EnableIRQ(BUTTON_SELECT_VECTOR);
gpio_register_callback(btn_callback, BUTTON_SELECT_PORT, BUTTON_SELECT_PIN);
return 1;
@ -159,7 +159,7 @@ config_left(int type, int value)
ioc_set_over(BUTTON_LEFT_PORT, BUTTON_LEFT_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(BUTTON_LEFT_VECTOR);
NVIC_EnableIRQ(BUTTON_LEFT_VECTOR);
gpio_register_callback(btn_callback, BUTTON_LEFT_PORT, BUTTON_LEFT_PIN);
return 1;
@ -183,7 +183,7 @@ config_right(int type, int value)
ioc_set_over(BUTTON_RIGHT_PORT, BUTTON_RIGHT_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(BUTTON_RIGHT_VECTOR);
NVIC_EnableIRQ(BUTTON_RIGHT_VECTOR);
gpio_register_callback(btn_callback, BUTTON_RIGHT_PORT, BUTTON_RIGHT_PIN);
return 1;
@ -207,7 +207,7 @@ config_up(int type, int value)
ioc_set_over(BUTTON_UP_PORT, BUTTON_UP_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(BUTTON_UP_VECTOR);
NVIC_EnableIRQ(BUTTON_UP_VECTOR);
gpio_register_callback(btn_callback, BUTTON_UP_PORT, BUTTON_UP_PIN);
return 1;
@ -231,7 +231,7 @@ config_down(int type, int value)
ioc_set_over(BUTTON_DOWN_PORT, BUTTON_DOWN_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(BUTTON_DOWN_VECTOR);
NVIC_EnableIRQ(BUTTON_DOWN_VECTOR);
gpio_register_callback(btn_callback, BUTTON_DOWN_PORT, BUTTON_DOWN_PIN);
return 1;

View file

@ -125,7 +125,7 @@
/** BUTTON_USER -> PC3 */
#define BUTTON_USER_PORT GPIO_C_NUM
#define BUTTON_USER_PIN 3
#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_C
#define BUTTON_USER_VECTOR GPIO_C_IRQn
/* Notify various examples that we have Buttons */
#define PLATFORM_HAS_BUTTON 1
/** @} */

View file

@ -48,7 +48,6 @@
#include "contiki.h"
#include "dev/leds.h"
#include "dev/sys-ctrl.h"
#include "dev/scb.h"
#include "dev/nvic.h"
#include "dev/uart.h"
#include "dev/i2c.h"

View file

@ -158,10 +158,10 @@ config_user(int type, int value)
case SENSORS_ACTIVE:
if(value) {
GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
nvic_interrupt_enable(BUTTON_USER_VECTOR);
NVIC_EnableIRQ(BUTTON_USER_VECTOR);
} else {
GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
nvic_interrupt_disable(BUTTON_USER_VECTOR);
NVIC_DisableIRQ(BUTTON_USER_VECTOR);
}
return value;
case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL:

View file

@ -47,7 +47,6 @@
#include "contiki.h"
#include "dev/leds.h"
#include "dev/sys-ctrl.h"
#include "dev/scb.h"
#include "dev/nvic.h"
#include "dev/uart.h"
#include "dev/watchdog.h"

View file

@ -137,7 +137,7 @@ configure(int type, int value)
/* Enable interrupts */
GPIO_ENABLE_INTERRUPT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
// ioc_set_over(DIMMER_SYNC_PORT, DIMMER_SYNC_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(DIMMER_INT_VECTOR);
NVIC_EnableIRQ(DIMMER_INT_VECTOR);
enabled = 1;
dimming = DIMMER_DEFAULT_START_VALUE;

View file

@ -73,7 +73,7 @@
#ifdef DIMMER_CONF_INT_VECTOR
#define DIMMER_INT_VECTOR DIMMER_CONF_INT_VECTOR
#else
#define DIMMER_INT_VECTOR NVIC_INT_GPIO_PORT_A
#define DIMMER_INT_VECTOR GPIO_A_IRQn
#endif
/** @} */
/* -------------------------------------------------------------------------- */

View file

@ -157,10 +157,10 @@ config_user(int type, int value)
case SENSORS_ACTIVE:
if(value) {
GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
nvic_interrupt_enable(BUTTON_USER_VECTOR);
NVIC_EnableIRQ(BUTTON_USER_VECTOR);
} else {
GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK);
nvic_interrupt_disable(BUTTON_USER_VECTOR);
NVIC_DisableIRQ(BUTTON_USER_VECTOR);
}
return value;
case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL:

View file

@ -183,7 +183,7 @@ cc1200_arch_gpio0_setup_irq(int rising)
GPIO_ENABLE_INTERRUPT(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK);
ioc_set_over(CC1200_GDO0_PORT, CC1200_GDO0_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(CC1200_GPIOx_VECTOR);
NVIC_EnableIRQ(CC1200_GPIOx_VECTOR);
gpio_register_callback(cc1200_int_handler, CC1200_GDO0_PORT,
CC1200_GDO0_PIN);
}
@ -205,7 +205,7 @@ cc1200_arch_gpio2_setup_irq(int rising)
GPIO_ENABLE_INTERRUPT(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK);
ioc_set_over(CC1200_GDO2_PORT, CC1200_GDO2_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(CC1200_GPIOx_VECTOR);
NVIC_EnableIRQ(CC1200_GPIOx_VECTOR);
gpio_register_callback(cc1200_int_handler, CC1200_GDO2_PORT,
CC1200_GDO2_PIN);
}
@ -215,7 +215,7 @@ cc1200_arch_gpio0_enable_irq(void)
{
GPIO_ENABLE_INTERRUPT(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK);
ioc_set_over(CC1200_GDO0_PORT, CC1200_GDO0_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(CC1200_GPIOx_VECTOR);
NVIC_EnableIRQ(CC1200_GPIOx_VECTOR);
}
/*---------------------------------------------------------------------------*/
void
@ -229,7 +229,7 @@ cc1200_arch_gpio2_enable_irq(void)
{
GPIO_ENABLE_INTERRUPT(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK);
ioc_set_over(CC1200_GDO2_PORT, CC1200_GDO2_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(CC1200_GPIOx_VECTOR);
NVIC_EnableIRQ(CC1200_GPIOx_VECTOR);
}
/*---------------------------------------------------------------------------*/
void

View file

@ -603,7 +603,7 @@ configure(int type, int value)
int_en = 1;
GPIO_ENABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK);
ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(I2C_INT_VECTOR);
NVIC_EnableIRQ(I2C_INT_VECTOR);
PRINTF("Gyro: Data interrupt configured\n");
return GROVE_GYRO_SUCCESS;

View file

@ -119,7 +119,7 @@ configure(int type, int value)
process_start(&motion_int_process, NULL);
GPIO_ENABLE_INTERRUPT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK);
nvic_interrupt_enable(MOTION_SENSOR_VECTOR);
NVIC_EnableIRQ(MOTION_SENSOR_VECTOR);
return MOTION_SUCCESS;
}
/*---------------------------------------------------------------------------*/

View file

@ -523,7 +523,7 @@ rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat,
} else {
GPIO_ENABLE_INTERRUPT(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK);
ioc_set_over(RTC_INT1_PORT, RTC_INT1_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(RTC_INT1_VECTOR);
NVIC_EnableIRQ(RTC_INT1_VECTOR);
}
if (trigger == RTCC_TRIGGER_INT1) {

View file

@ -453,7 +453,7 @@ configure(int type, int value)
* resistor instead if no external pull-up is present.
*/
ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE);
nvic_interrupt_enable(I2C_INT_VECTOR);
NVIC_EnableIRQ(I2C_INT_VECTOR);
PRINTF("TSL256X: Interrupt configured\n");
return TSL256X_SUCCESS;

View file

@ -449,8 +449,8 @@ configure(int type, int value)
GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK);
GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK);
nvic_interrupt_enable(ANEMOMETER_SENSOR_VECTOR);
nvic_interrupt_enable(RAIN_GAUGE_SENSOR_VECTOR);
NVIC_EnableIRQ(ANEMOMETER_SENSOR_VECTOR);
NVIC_EnableIRQ(RAIN_GAUGE_SENSOR_VECTOR);
enabled = 1;
PRINTF("Weather: started\n");

View file

@ -118,7 +118,7 @@ extern void (*rain_gauge_int_callback)(uint16_t value);
#ifdef WEATHER_METER_CONF_ANEMOMETER_VECTOR
#define ANEMOMETER_SENSOR_VECTOR WEATHER_METER_CONF_ANEMOMETER_VECTOR
#else
#define ANEMOMETER_SENSOR_VECTOR NVIC_INT_GPIO_PORT_D
#define ANEMOMETER_SENSOR_VECTOR GPIO_D_IRQn
#endif
/** @} */
/* -------------------------------------------------------------------------- */
@ -139,7 +139,7 @@ extern void (*rain_gauge_int_callback)(uint16_t value);
#ifdef WEATHER_METER_CONF_RAIN_GAUGE_VECTOR
#define RAIN_GAUGE_SENSOR_VECTOR WEATHER_METER_CONF_RAIN_GAUGE_VECTOR
#else
#define RAIN_GAUGE_SENSOR_VECTOR NVIC_INT_GPIO_PORT_D
#define RAIN_GAUGE_SENSOR_VECTOR GPIO_D_IRQn
#endif
/** @} */
/* -------------------------------------------------------------------------- */

View file

@ -265,7 +265,7 @@
/** BUTTON_USER -> PA3 */
#define BUTTON_USER_PORT GPIO_A_NUM
#define BUTTON_USER_PIN 3
#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A
#define BUTTON_USER_VECTOR GPIO_A_IRQn
/* Notify various examples that we have an user button.
* If ADC6 channel is used, then disable the user button
@ -330,7 +330,7 @@
#define I2C_SDA_PIN 2
#define I2C_INT_PORT GPIO_D_NUM
#define I2C_INT_PIN 1
#define I2C_INT_VECTOR NVIC_INT_GPIO_PORT_D
#define I2C_INT_VECTOR GPIO_D_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**
@ -368,7 +368,7 @@
#define CC1200_GDO2_PIN 0
#define CC1200_RESET_PORT GPIO_C_NUM
#define CC1200_RESET_PIN 7
#define CC1200_GPIOx_VECTOR NVIC_INT_GPIO_PORT_B
#define CC1200_GPIOx_VECTOR GPIO_B_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**

View file

@ -264,7 +264,7 @@
/** BUTTON_USER -> PA3 */
#define BUTTON_USER_PORT GPIO_A_NUM
#define BUTTON_USER_PIN 3
#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A
#define BUTTON_USER_VECTOR GPIO_A_IRQn
/* Notify various examples that we have an user button.
* If ADC6 channel is used, then disable the user button
@ -329,7 +329,7 @@
#define I2C_SDA_PIN 2
#define I2C_INT_PORT GPIO_D_NUM
#define I2C_INT_PIN 1
#define I2C_INT_VECTOR NVIC_INT_GPIO_PORT_D
#define I2C_INT_VECTOR GPIO_D_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**
@ -367,7 +367,7 @@
#define CC1200_GDO2_PIN 0
#define CC1200_RESET_PORT GPIO_C_NUM
#define CC1200_RESET_PIN 7
#define CC1200_GPIOx_VECTOR NVIC_INT_GPIO_PORT_B
#define CC1200_GPIOx_VECTOR GPIO_B_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**

View file

@ -268,7 +268,7 @@
/** BUTTON_USER -> PA3 */
#define BUTTON_USER_PORT GPIO_A_NUM
#define BUTTON_USER_PIN 3
#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A
#define BUTTON_USER_VECTOR GPIO_A_IRQn
/* Notify various examples that we have an user button.
* If ADC6 channel is used, then disable the user button
@ -336,7 +336,7 @@
#define I2C_SDA_PIN 2
#define I2C_INT_PORT GPIO_D_NUM
#define I2C_INT_PIN 1
#define I2C_INT_VECTOR NVIC_INT_GPIO_PORT_D
#define I2C_INT_VECTOR GPIO_D_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**
@ -395,7 +395,7 @@
#define CC1200_GDO2_PIN 0
#define CC1200_RESET_PORT GPIO_C_NUM
#define CC1200_RESET_PIN 7
#define CC1200_GPIOx_VECTOR NVIC_INT_GPIO_PORT_B
#define CC1200_GPIOx_VECTOR GPIO_B_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**
@ -460,7 +460,7 @@
#define RTC_SCL_PIN I2C_SCL_PIN
#define RTC_INT1_PORT GPIO_A_NUM
#define RTC_INT1_PIN 4
#define RTC_INT1_VECTOR NVIC_INT_GPIO_PORT_A
#define RTC_INT1_VECTOR GPIO_A_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**

View file

@ -293,7 +293,7 @@
*/
#define BUTTON_USER_PORT GPIO_A_NUM
#define BUTTON_USER_PIN 3
#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A
#define BUTTON_USER_VECTOR GPIO_A_IRQn
/* Notify various examples that we have an user button.
* If ADC6 channel is used, then disable the user button
@ -360,7 +360,7 @@
#define I2C_SDA_PIN 2
#define I2C_INT_PORT GPIO_D_NUM
#define I2C_INT_PIN 0
#define I2C_INT_VECTOR NVIC_INT_GPIO_PORT_D
#define I2C_INT_VECTOR GPIO_D_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**
@ -419,7 +419,7 @@
#define CC1200_GDO2_PIN 0
#define CC1200_RESET_PORT GPIO_C_NUM
#define CC1200_RESET_PIN 7
#define CC1200_GPIOx_VECTOR NVIC_INT_GPIO_PORT_B
#define CC1200_GPIOx_VECTOR GPIO_B_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**
@ -487,7 +487,7 @@
#define RTC_SCL_PIN I2C_SCL_PIN
#define RTC_INT1_PORT GPIO_D_NUM
#define RTC_INT1_PIN 3
#define RTC_INT1_VECTOR NVIC_INT_GPIO_PORT_D
#define RTC_INT1_VECTOR GPIO_D_IRQn
/** @} */
/*---------------------------------------------------------------------------*/
/**