mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
535fff26ae
Signed-off-by: Francois Berder <18538310+francois-berder@users.noreply.github.com>
96 lines
2.6 KiB
C
96 lines
2.6 KiB
C
/*
|
|
* Copyright (C) 2019 Francois Berder
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*
|
|
*/
|
|
|
|
#include "cpu_conf.h"
|
|
#include "eic.h"
|
|
#include <stdint.h>
|
|
|
|
#if defined(CPU_FAM_PIC32MX)
|
|
#define VEC_NUMOF (64)
|
|
#elif defined (CPU_FAM_PIC32MZ)
|
|
#define VEC_NUMOF (256)
|
|
#endif
|
|
|
|
#define IECSET(V) *(volatile uint32_t *)((uintptr_t)&IEC0SET + 0x10 * ((V) / 32))
|
|
#define IECCLR(V) *(volatile uint32_t *)((uintptr_t)&IEC0CLR + 0x10 * ((V) / 32))
|
|
#define IFSCLR(V) *(volatile uint32_t *)((uintptr_t)&IFS0CLR + 0x10 * ((V) / 32))
|
|
#define IPC(V) *(volatile uint32_t *)((uintptr_t)&IPC0 + 0x10 * ((V) / 4))
|
|
|
|
static external_isr_ptr_t vectors[VEC_NUMOF];
|
|
|
|
void set_external_isr_cb(int vecNum, external_isr_ptr_t cbFunc)
|
|
{
|
|
if (vecNum < VEC_NUMOF)
|
|
vectors[vecNum] = cbFunc;
|
|
}
|
|
|
|
/* note Compiler inserts GP context save + restore code (to current stack). */
|
|
/*
|
|
* This is a hack - currently the toolchain does not support correct placement
|
|
* of EIC mode vectors (it is coming though) But we can support non-vectored EIC
|
|
* mode and note the default PIC32 interrupt controller (which uses EIC +
|
|
* MCU-ASE) defaults to non vectored mode anyway with all interrupts coming via
|
|
* vector 0 which is equivalent to 'sw0' in 'VI' mode.
|
|
*
|
|
* Thus all EIC interrupts should be decoded here.
|
|
*
|
|
* When toolchain support is available we could move to full vector mode but
|
|
* this does take up significant space (MCU-ASE provides 256 vectors at 32B
|
|
* spacing (the default) that's 8KB of vector space!), So a single entry point
|
|
* may be better anyway.
|
|
*
|
|
*/
|
|
void __attribute__ ((interrupt("vector=sw0"), keep_interrupts_masked)) _mips_isr_sw0(void)
|
|
{
|
|
#if defined(CPU_FAM_PIC32MX)
|
|
int vecNum = INTSTAT & _INTSTAT_VEC_MASK;
|
|
#elif defined (CPU_FAM_PIC32MZ)
|
|
int vecNum = INTSTAT & _INTSTAT_SIRQ_MASK;
|
|
#endif
|
|
|
|
if (vectors[vecNum])
|
|
vectors[vecNum]();
|
|
}
|
|
|
|
void eic_configure_priority(int vecNum, int priority, int subpriority)
|
|
{
|
|
unsigned int offset;
|
|
|
|
if (vecNum >= VEC_NUMOF)
|
|
return;
|
|
|
|
offset = 8 * (vecNum & 0x3);
|
|
IPC(vecNum) &= ~(0x1F << offset);
|
|
IPC(vecNum) |= ((priority << 2) | (subpriority)) << offset;
|
|
}
|
|
|
|
void eic_enable(int vecNum)
|
|
{
|
|
if (vecNum >= VEC_NUMOF)
|
|
return;
|
|
|
|
IECSET(vecNum) = 1U << (vecNum & 0x1F);
|
|
}
|
|
|
|
void eic_disable(int vecNum)
|
|
{
|
|
if (vecNum >= VEC_NUMOF)
|
|
return;
|
|
|
|
IECCLR(vecNum) = 1U << (vecNum & 0x1F);
|
|
}
|
|
|
|
void eic_clear_flag(int vecNum)
|
|
{
|
|
if (vecNum >= VEC_NUMOF)
|
|
return;
|
|
|
|
IFSCLR(vecNum) = 1U << (vecNum & 0x1F);
|
|
}
|