OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [neorv32_xirq.c] - Diff between revs 61 and 64

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 61 Rev 64
Line 47... Line 47...
 * The >private< trap vector look-up table of the XIRQ.
 * The >private< trap vector look-up table of the XIRQ.
 **************************************************************************/
 **************************************************************************/
static uint32_t __neorv32_xirq_vector_lut[32] __attribute__((unused)); // trap handler vector table
static uint32_t __neorv32_xirq_vector_lut[32] __attribute__((unused)); // trap handler vector table
 
 
// private functions
// private functions
static void __attribute__((aligned(16))) __attribute__((unused)) __neorv32_xirq_core(void);
static void __attribute__((aligned(16))) __neorv32_xirq_core(void);
static void __attribute__((unused)) __neorv32_xirq_dummy_handler(void);
static void __neorv32_xirq_dummy_handler(void);
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Check if external interrupt controller was synthesized.
 * Check if external interrupt controller was synthesized.
 *
 *
 * @return 0 if XIRQ was not synthesized, 1 if EXTIRQ is available.
 * @return 0 if XIRQ was not synthesized, 1 if EXTIRQ is available.
 **************************************************************************/
 **************************************************************************/
int neorv32_xirq_available(void) {
int neorv32_xirq_available(void) {
 
 
  if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_XIRQ)) {
  if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_XIRQ)) {
    return 1;
    return 1;
  }
  }
  else {
  else {
    return 0;
    return 0;
  }
  }
Line 76... Line 76...
 * handler addresses will be deleted.
 * handler addresses will be deleted.
 * @return 0 if success, 1 if error.
 * @return 0 if success, 1 if error.
 **************************************************************************/
 **************************************************************************/
int neorv32_xirq_setup(void) {
int neorv32_xirq_setup(void) {
 
 
  XIRQ_IER = 0; // disable all input channels
  NEORV32_XIRQ.IER = 0; // disable all input channels
  XIRQ_IPR = 0xffffffff; // clear/ack all pending IRQs
  NEORV32_XIRQ.IPR = 0; // clear all pending IRQs
 
 
  int i;
  int i;
  for (i=0; i<32; i++) {
  for (i=0; i<32; i++) {
    __neorv32_xirq_vector_lut[i] = (uint32_t)(&__neorv32_xirq_dummy_handler);
    __neorv32_xirq_vector_lut[i] = (uint32_t)(&__neorv32_xirq_dummy_handler);
  }
  }
 
 
  // register XIRQ handler in RTE
  // register XIRQ handler in NEORV32 RTE
  return neorv32_rte_exception_install(XIRQ_RTE_ID, __neorv32_xirq_core);
  return neorv32_rte_exception_install(XIRQ_RTE_ID, __neorv32_xirq_core);
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
Line 122... Line 122...
  int i, cnt;
  int i, cnt;
 
 
  if (neorv32_xirq_available()) {
  if (neorv32_xirq_available()) {
 
 
    neorv32_cpu_irq_disable(XIRQ_FIRQ_ENABLE); // make sure XIRQ cannot fire
    neorv32_cpu_irq_disable(XIRQ_FIRQ_ENABLE); // make sure XIRQ cannot fire
    XIRQ_IER = 0xffffffff; // try to set all enable flags
    NEORV32_XIRQ.IER = 0xffffffff; // try to set all enable flags
    enable = XIRQ_IER; // read back actually set flags
    enable = NEORV32_XIRQ.IER; // read back actually set flags
 
 
    // count set bits in enable
    // count set bits in enable
    cnt = 0;
    cnt = 0;
    for (i=0; i<32; i++) {
    for (i=0; i<32; i++) {
      if (enable & 1) {
      if (enable & 1) {
Line 142... Line 142...
  }
  }
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 
 * Clear pending interrupt.
 
 *
 
 * @param[in] ch XIRQ interrupt channel (0..31).
 
 **************************************************************************/
 
void neorv32_xirq_clear_pending(uint8_t ch) {
 
 
 
  if (ch < 32) { // channel valid?
 
    NEORV32_XIRQ.IPR = ~(1 << ch);
 
  }
 
}
 
 
 
 
 
/**********************************************************************//**
 
 * Enable IRQ channel.
 
 *
 
 * @param[in] ch XIRQ interrupt channel (0..31).
 
 **************************************************************************/
 
void neorv32_xirq_channel_enable(uint8_t ch) {
 
 
 
  if (ch < 32) { // channel valid?
 
    NEORV32_XIRQ.IER |= 1 << ch;
 
  }
 
}
 
 
 
 
 
/**********************************************************************//**
 
 * Disable IRQ channel.
 
 *
 
 * @param[in] ch XIRQ interrupt channel (0..31).
 
 **************************************************************************/
 
void neorv32_xirq_channel_disable(uint8_t ch) {
 
 
 
  if (ch < 32) { // channel valid?
 
    NEORV32_XIRQ.IER &= ~(1 << ch);
 
  }
 
}
 
 
 
 
 
/**********************************************************************//**
 * Install exception handler function for XIRQ channel.
 * Install exception handler function for XIRQ channel.
 *
 *
 * @note This will also activate the according XIRQ channel and clear a pending IRQ at this channel.
 * @note This will also activate the according XIRQ channel and clear a pending IRQ at this channel.
 *
 *
 * @param[in] ch XIRQ interrupt channel (0..31).
 * @param[in] ch XIRQ interrupt channel (0..31).
Line 156... Line 195...
 
 
  // channel valid?
  // channel valid?
  if (ch < 32) {
  if (ch < 32) {
    __neorv32_xirq_vector_lut[ch] = (uint32_t)handler; // install handler
    __neorv32_xirq_vector_lut[ch] = (uint32_t)handler; // install handler
    uint32_t mask = 1 << ch;
    uint32_t mask = 1 << ch;
    XIRQ_IPR = mask; // clear if pending
    NEORV32_XIRQ.IPR = ~mask; // clear if pending
    XIRQ_IER |= mask; // enable channel
    NEORV32_XIRQ.IER |= mask; // enable channel
    return 0;
    return 0;
  }
  }
  return 1;
  return 1;
}
}
 
 
Line 178... Line 217...
 
 
  // channel valid?
  // channel valid?
  if (ch < 32) {
  if (ch < 32) {
    __neorv32_xirq_vector_lut[ch] = (uint32_t)(&__neorv32_xirq_dummy_handler); // override using dummy handler
    __neorv32_xirq_vector_lut[ch] = (uint32_t)(&__neorv32_xirq_dummy_handler); // override using dummy handler
    uint32_t mask = 1 << ch;
    uint32_t mask = 1 << ch;
    XIRQ_IER &= ~mask; // disable channel
    NEORV32_XIRQ.IER &= ~mask; // disable channel
    XIRQ_IPR = mask; // clear if pending
    NEORV32_XIRQ.IPR = ~mask; // clear if pending
    return 0;
    return 0;
  }
  }
  return 1;
  return 1;
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * This is the actual second-level IRQ handler for the XIRQ. It will call the previously installed handler
 * This is the actual second-level (F)IRQ handler for the XIRQ. It will
 * if an XIRQ fires.
 * call the previously installed handler if an XIRQ fires.
 *
 
 * @note This function must no be used by the user.
 
 **************************************************************************/
 **************************************************************************/
static void __attribute__((aligned(16))) __attribute__((unused)) __neorv32_xirq_core(void) {
static void __attribute__((aligned(16))) __neorv32_xirq_core(void) {
 
 
  register uint32_t src = XIRQ_SCR; // get IRQ source (with highest priority)
  register uint32_t src = NEORV32_XIRQ.SCR; // get IRQ source (with highest priority)
  src &= 0x1f;
 
 
 
  XIRQ_IPR = (uint32_t)(1 << src); // acknowledge pending interrupt
  uint32_t mask = 1 << src;
 
  NEORV32_XIRQ.IPR = ~mask; // clear current pending interrupt
 
  NEORV32_XIRQ.SCR = 0; // acknowledge current interrupt (CPU FIRQ)
 
 
  // execute handler
  // execute handler
  register uint32_t xirq_handler = __neorv32_xirq_vector_lut[src];
  register uint32_t xirq_handler = __neorv32_xirq_vector_lut[src];
  void (*handler_pnt)(void);
  void (*handler_pnt)(void);
  handler_pnt = (void*)xirq_handler;
  handler_pnt = (void*)xirq_handler;
Line 210... Line 248...
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * XIRQ dummy handler.
 * XIRQ dummy handler.
 **************************************************************************/
 **************************************************************************/
static void __attribute__((unused)) __neorv32_xirq_dummy_handler(void) {
static void __neorv32_xirq_dummy_handler(void) {
 
 
  asm volatile ("nop");
  asm volatile ("nop");
}
}
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.