88 lines
2.2 KiB
C
88 lines
2.2 KiB
C
/** @file nvic.c
|
|
* Module handling the Nested Vector Interrupt Controller (NVIC)
|
|
*
|
|
* The module provides functions to configure the different interrupts and
|
|
* their priority suiing the NVIC's interface
|
|
*/
|
|
|
|
//--includes--------------------------------------------------------------------
|
|
|
|
#include "nvic.h"
|
|
#include "nvic_regs.h"
|
|
|
|
|
|
//--local definitions-----------------------------------------------------------
|
|
|
|
/**
|
|
* NVIC's register are only accessible by 32 bits words, and data is stored
|
|
* accors 3 consecutive registers. This macro sets the right bit from the
|
|
* right register based on the IRQ number
|
|
*/
|
|
#define set_bit(reg, irq) \
|
|
do { \
|
|
uint8_t n = irq / 32; \
|
|
uint8_t r = irq - n * 32; \
|
|
regs->reg[n] |= (0x1 << r); \
|
|
} while (0)
|
|
|
|
/**
|
|
* NVIC's register are only accessible by 32 bits words, and data is stored
|
|
* accors 3 consecutive registers. This macro fetches the right bit from the
|
|
* right register based on the IRQ number
|
|
*/
|
|
#define get_bit(reg, irq, res) \
|
|
do { \
|
|
uint8_t n = irq / 32; \
|
|
uint8_t r = irq - n * 32; \
|
|
res = 0 != (regs->reg[n] | (0x1 << r)); \
|
|
} while (0)
|
|
|
|
|
|
//--local variables-------------------------------------------------------------
|
|
|
|
static volatile struct NVIC1* regs = (struct NVIC1*)NVIC1_BASE_ADDRESS;
|
|
|
|
|
|
//--public functions------------------------------------------------------------
|
|
|
|
void nvic_enable(enum NvicIrq irq)
|
|
{
|
|
set_bit(ISERX, irq);
|
|
}
|
|
|
|
void nvic_disable(enum NvicIrq irq)
|
|
{
|
|
set_bit(ICERX, irq);
|
|
}
|
|
|
|
void nvic_clear_pending(enum NvicIrq irq)
|
|
{
|
|
set_bit(ICPRX, irq);
|
|
}
|
|
|
|
void nvic_set_priority(enum NvicIrq irq, uint8_t priority)
|
|
{
|
|
uint8_t n = irq / 4;
|
|
uint8_t r = (irq - n * 4); //get the division's reminder
|
|
r *= 8; //mul by 8 since each 'slot' is 8 bits
|
|
r += 4; //add 4 since we only write to the upper 4 bits
|
|
regs->IPRX[n] &= ~(0x0F << r);
|
|
regs->IPRX[n] |= (priority & 0x0F) << r;
|
|
}
|
|
|
|
void nvic_set_pending(enum NvicIrq irq)
|
|
{
|
|
set_bit(ISPRX, irq);
|
|
}
|
|
|
|
bool nvic_is_pending(enum NvicIrq irq)
|
|
{
|
|
bool res = false;
|
|
get_bit(ISPRX, irq, res);
|
|
return res;
|
|
}
|
|
|
|
|
|
//--local functions-------------------------------------------------------------
|
|
|