/* * File: dyn_SWI.h * Author: xxxajk@gmail.com * * Created on December 5, 2014, 9:12 AM * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DYN_SWI_H #define DYN_SWI_H #if defined(__arm__) || defined(ARDUINO_ARCH_PIC32) #ifdef ARDUINO_ARCH_PIC32 #include #endif #ifdef __cplusplus #ifdef true #undef true #endif #ifdef false #undef false #endif #endif #ifdef ARDUINO_spresense_ast #define SWI_IRQ_NUM 666 // because this board is totally evil. #elif defined(ARDUINO_ARCH_PIC32) #ifndef SWI_IRQ_NUM #ifdef _DSPI0_IPL_ISR #define SWI_IPL _DSPI0_IPL_ISR #define SWI_VECTOR _DSPI0_ERR_IRQ #define SWI_IRQ_NUM _DSPI0_ERR_IRQ #elif defined(_PMP_ERROR_IRQ) #define SWI_IRQ_NUM _PMP_ERROR_IRQ #define SWI_VECTOR _PMP_VECTOR #else #error SWI_IRQ_NUM and SWI_VECTOR need a definition #endif #ifdef __cplusplus extern "C" { void #ifdef __PIC32MZXX__ __attribute__((nomips16,at_vector(SWI_VECTOR),interrupt(SWI_IPL))) #else __attribute__((interrupt(),nomips16)) #endif softISR(); } #endif #endif #elif !defined(NVIC_NUM_INTERRUPTS) // Assume CMSIS #define __USE_CMSIS_VECTORS__ #ifdef NUMBER_OF_INT_VECTORS #define NVIC_NUM_INTERRUPTS (NUMBER_OF_INT_VECTORS-16) #else #define NVIC_NUM_INTERRUPTS ((int)PERIPH_COUNT_IRQn) #endif #define VECTORTABLE_SIZE (NVIC_NUM_INTERRUPTS+16) #define VECTORTABLE_ALIGNMENT (0x100UL) #define NVIC_GET_ACTIVE(n) NVIC_GetActive((IRQn_Type)n) #define NVIC_GET_PENDING(n) NVIC_GetPendingIRQ((IRQn_Type)n) #define NVIC_SET_PENDING(n) NVIC_SetPendingIRQ((IRQn_Type)n) #define NVIC_ENABLE_IRQ(n) NVIC_EnableIRQ((IRQn_Type)n) #define NVIC_SET_PRIORITY(n ,p) NVIC_SetPriority((IRQn_Type)n, (uint32_t) p) //extern "C" { // extern uint32_t _VectorsRam[VECTORTABLE_SIZE] __attribute__((aligned(VECTORTABLE_ALIGNMENT))); //} #ifndef SWI_IRQ_NUM #if defined(__SAM3X8E__) && defined(_VARIANT_ARDUINO_DUE_X_) // DUE // Choices available: // HSMCI_IRQn Multimedia Card Interface (HSMCI) // EMAC_IRQn Ethernet MAC (EMAC) // EMAC is not broken out on the official DUE, but is on clones. // SPI0_IRQn Serial Peripheral Interface (SPI0) // SPI0_IRQn seems to be the best choice, as long as nobody uses an ISR based master #define SWI_IRQ_NUM SPI0_IRQn #elif defined(ARDUINO_SAMD_ZERO) // Just use sercom4's unused IRQ vector. #define SWI_IRQ_NUM I2S_IRQn //#define SWI_IRQ_NUM SERCOM4_IRQn #endif #endif #ifndef SWI_IRQ_NUM #error SWI_IRQ_NUM not defined (CMSIS) #endif #elif defined(CORE_TEENSY) #ifndef NVIC_GET_ACTIVE #define NVIC_GET_ACTIVE(n) (*((volatile uint32_t *)0xE000E300 + ((n) >> 5)) & (1 << ((n) & 31))) #endif #ifndef NVIC_GET_PENDING #define NVIC_GET_PENDING(n) (*((volatile uint32_t *)0xE000E200 + ((n) >> 5)) & (1 << ((n) & 31))) #ifndef SWI_IRQ_NUM #ifdef __MK20DX256__ #define SWI_IRQ_NUM 17 #elif defined(__MK20DX128__) #define SWI_IRQ_NUM 5 #elif defined(__MKL26Z64__) #define SWI_IRQ_NUM 4 #elif defined(__MK66FX1M0__) #define SWI_IRQ_NUM 30 #elif defined(__MK64FX512__) #define SWI_IRQ_NUM 30 #elif defined(__IMXRT1052__) || defined(__IMXRT1062__) #define SWI_IRQ_NUM 71 #else #error Do not know how to relocate IRQ vectors for this pjrc product #endif #endif #endif #else // Not CMSIS or PJRC CORE_TEENSY or PIC32 or SPRESENSE #error Do not know how to relocate IRQ vectors or perform SWI #endif // SWI_IRQ_NUM #ifndef SWI_IRQ_NUM #error SWI_IRQ_NUM not defined #else /** * Use this class to extend your class, in order to provide * a C++ context callable SWI. */ class dyn_SWI { public: /** * Override this method with your code. */ virtual void dyn_SWISR() { }; }; extern int exec_SWI(const dyn_SWI* klass); #include "SWI_INLINE.h" // IMPORTANT! Define this so that you do NOT end up with a NULL stub! #define SWI_NO_STUB #endif /* SWI_IRQ_NUM */ #endif /* __arm__ */ // if no SWI for CPU (e.g. AVR) make a void stub. #ifndef SWI_NO_STUB #define Init_dyn_SWI() (void(0)) #ifndef DDSB #define DDSB() (void(0)) #endif #endif #endif /* DYN_SWI_H */