rework #4
87
drivers/nvic.c
Normal file
87
drivers/nvic.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/** @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-------------------------------------------------------------
|
||||||
|
|
||||||
125
drivers/nvic.h
Normal file
125
drivers/nvic.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/** @file nvic.h
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NVIC_H_
|
||||||
|
#define _NVIC_H_
|
||||||
|
|
||||||
|
//--includes--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
|
||||||
|
|
||||||
|
//--type definitions------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available System IRQs. This does not include CPU's IRQs
|
||||||
|
*/
|
||||||
|
enum NvicIrq {
|
||||||
|
NVIC_IRQ_WWDG = 0,
|
||||||
|
NVIC_IRQ_PVD,
|
||||||
|
NVIC_IRQ_TAMPER,
|
||||||
|
NVIC_IRQ_RTC,
|
||||||
|
NVIC_IRQ_FLASH,
|
||||||
|
NVIC_IRQ_RCC,
|
||||||
|
NVIC_IRQ_EXTI0,
|
||||||
|
NVIC_IRQ_EXTI1,
|
||||||
|
NVIC_IRQ_EXTI2,
|
||||||
|
NVIC_IRQ_EXTI3,
|
||||||
|
NVIC_IRQ_EXTI4,
|
||||||
|
NVIC_IRQ_DMA1_CHANNEL1,
|
||||||
|
NVIC_IRQ_DMA1_CHANNEL2,
|
||||||
|
NVIC_IRQ_DMA1_CHANNEL3,
|
||||||
|
NVIC_IRQ_DMA1_CHANNEL4,
|
||||||
|
NVIC_IRQ_DMA1_CHANNEL5,
|
||||||
|
NVIC_IRQ_DMA1_CHANNEL6,
|
||||||
|
NVIC_IRQ_DMA1_CHANNEL7,
|
||||||
|
NVIC_IRQ_ADC1_2,
|
||||||
|
NVIC_IRQ_HP_CAN_TX,
|
||||||
|
NVIC_IRQ_LP_CAN_RX0,
|
||||||
|
NVIC_IRQ_CAN_RX1,
|
||||||
|
NVIC_IRQ_CAN_SCE,
|
||||||
|
NVIC_IRQ_EXTI9_5,
|
||||||
|
NVIC_IRQ_TIM1_BRK,
|
||||||
|
NVIC_IRQ_TIM1_UP,
|
||||||
|
NVIC_IRQ_TIM1_TRG_COM,
|
||||||
|
NVIC_IRQ_TIM1_CC,
|
||||||
|
NVIC_IRQ_TIM2,
|
||||||
|
NVIC_IRQ_TIM3,
|
||||||
|
NVIC_IRQ_TIM4,
|
||||||
|
NVIC_IRQ_I2C1_EVENT,
|
||||||
|
NVIC_IRQ_I2C1_ERROR,
|
||||||
|
NVIC_IRQ_I2C2_EVENT,
|
||||||
|
NVIC_IRQ_I2C2_ERROR,
|
||||||
|
NVIC_IRQ_SPI1,
|
||||||
|
NVIC_IRQ_SPI2,
|
||||||
|
NVIC_IRQ_USART1,
|
||||||
|
NVIC_IRQ_USART2,
|
||||||
|
NVIC_IRQ_USART3,
|
||||||
|
NVIC_IRQ_EXTI15_10,
|
||||||
|
NVIC_IRQ_RTC_ALARM,
|
||||||
|
NVIC_IRQ_USB_WAKEUP,
|
||||||
|
NVIC_IRQ_TIM8_BRK,
|
||||||
|
NVIC_IRQ_TIM8_UP,
|
||||||
|
NVIC_IRQ_TIM8_TRG_COM,
|
||||||
|
NVIC_IRQ_TIM8_CC,
|
||||||
|
NVIC_IRQ_ADC3,
|
||||||
|
NVIC_IRQ_FSMC,
|
||||||
|
NVIC_IRQ_SDIO,
|
||||||
|
NVIC_IRQ_TIM5,
|
||||||
|
NVIC_IRQ_SPI3,
|
||||||
|
NVIC_IRQ_UART4,
|
||||||
|
NVIC_IRQ_UART5,
|
||||||
|
NVIC_IRQ_TIM6,
|
||||||
|
NVIC_IRQ_TIM7,
|
||||||
|
NVIC_IRQ_DMA2_CHANNEL1,
|
||||||
|
NVIC_IRQ_DMA2_CHANNEL2,
|
||||||
|
NVIC_IRQ_DMA2_CHANNEL3,
|
||||||
|
NVIC_IRQ_DMA2_CHANNEL4_5,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//--functions-------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the selected IRQ
|
||||||
|
*/
|
||||||
|
void nvic_enable(enum NvicIrq irq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the selected IRQ
|
||||||
|
*/
|
||||||
|
void nvic_disable(enum NvicIrq irq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the pending state of an IRQ. Should be called when reaching an IRQ
|
||||||
|
* handler so that the IRQ isn't triggered again when exiting the handler
|
||||||
|
*/
|
||||||
|
void nvic_clear_pending(enum NvicIrq irq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the priority for the selected IRQ. The lower the priority value, the
|
||||||
|
* higher the effective priority. Valid priority values range from 0 to 15. Any
|
||||||
|
* higher value will be ignored. When multiple IRQs with the same priority are
|
||||||
|
* triggered, they will be serviced from the lowest ID to the highest
|
||||||
|
*/
|
||||||
|
void nvic_set_priority(enum NvicIrq irq, uint8_t priority);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the selected IRQ's pending state. If the IRQ is active, it will be
|
||||||
|
* triggered
|
||||||
|
*/
|
||||||
|
void nvic_set_pending(enum NvicIrq irq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns wether the selected IRQ is currently pending or not
|
||||||
|
*/
|
||||||
|
bool nvic_is_pending(enum NvicIrq irq);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_RCC_H_
|
||||||
|
|
||||||
113
startup.s
113
startup.s
@ -99,13 +99,13 @@ vector_table:
|
|||||||
.word hdr_exti2
|
.word hdr_exti2
|
||||||
.word hdr_exti3
|
.word hdr_exti3
|
||||||
.word hdr_exti4
|
.word hdr_exti4
|
||||||
.word hdr_dma_channel1
|
.word hdr_dma1_channel1
|
||||||
.word hdr_dma_channel2
|
.word hdr_dma1_channel2
|
||||||
.word hdr_dma_channel3
|
.word hdr_dma1_channel3
|
||||||
.word hdr_dma_channel4
|
.word hdr_dma1_channel4
|
||||||
.word hdr_dma_channel5
|
.word hdr_dma1_channel5
|
||||||
.word hdr_dma_channel6
|
.word hdr_dma1_channel6
|
||||||
.word hdr_dma_channel7
|
.word hdr_dma1_channel7
|
||||||
.word hdr_adc1_2
|
.word hdr_adc1_2
|
||||||
.word hdr_hp_can_tx
|
.word hdr_hp_can_tx
|
||||||
.word hdr_lp_can_rx0
|
.word hdr_lp_can_rx0
|
||||||
@ -131,23 +131,23 @@ vector_table:
|
|||||||
.word hdr_exti15_10
|
.word hdr_exti15_10
|
||||||
.word hdr_rtc_alarm
|
.word hdr_rtc_alarm
|
||||||
.word hdr_usb_wakeup
|
.word hdr_usb_wakeup
|
||||||
.word 0
|
.word hdr_tim8_brk
|
||||||
.word 0
|
.word hdr_tim8_up
|
||||||
.word 0
|
.word hdr_tim8_trg_com
|
||||||
.word 0
|
.word hdr_tim8_cc
|
||||||
.word 0
|
.word hdr_adc3
|
||||||
.word 0
|
.word hdr_fsmc
|
||||||
.word 0
|
.word hdr_sdio
|
||||||
.word 0
|
.word hdr_tim5
|
||||||
.word 0
|
.word hdr_spi3
|
||||||
.word 0
|
.word hdr_uart4
|
||||||
.word 0
|
.word hdr_uart5
|
||||||
.word 0
|
.word hdr_tim6
|
||||||
.word 0
|
.word hdr_tim7
|
||||||
.word 0
|
.word hdr_dma2_channel1
|
||||||
.word 0
|
.word hdr_dma2_channel2
|
||||||
.word 0
|
.word hdr_dma2_channel3
|
||||||
.word 0
|
.word hdr_dma2_channel4_5
|
||||||
|
|
||||||
//--Weak definitions------------------------------------------------------------
|
//--Weak definitions------------------------------------------------------------
|
||||||
|
|
||||||
@ -211,25 +211,25 @@ vector_table:
|
|||||||
.weak hdr_exti4
|
.weak hdr_exti4
|
||||||
.thumb_set hdr_exti4, hdr_default
|
.thumb_set hdr_exti4, hdr_default
|
||||||
|
|
||||||
.weak hdr_dma_channel1
|
.weak hdr_dma1_channel1
|
||||||
.thumb_set hdr_dma_channel1, hdr_default
|
.thumb_set hdr_dma_channel1, hdr_default
|
||||||
|
|
||||||
.weak hdr_dma_channel2
|
.weak hdr_dma1_channel2
|
||||||
.thumb_set hdr_dma_channel2, hdr_default
|
.thumb_set hdr_dma_channel2, hdr_default
|
||||||
|
|
||||||
.weak hdr_dma_channel3
|
.weak hdr_dma1_channel3
|
||||||
.thumb_set hdr_dma_channel3, hdr_default
|
.thumb_set hdr_dma_channel3, hdr_default
|
||||||
|
|
||||||
.weak hdr_dma_channel4
|
.weak hdr_dma1_channel4
|
||||||
.thumb_set hdr_dma_channel4, hdr_default
|
.thumb_set hdr_dma_channel4, hdr_default
|
||||||
|
|
||||||
.weak hdr_dma_channel5
|
.weak hdr_dma1_channel5
|
||||||
.thumb_set hdr_dma_channel5, hdr_default
|
.thumb_set hdr_dma_channel5, hdr_default
|
||||||
|
|
||||||
.weak hdr_dma_channel6
|
.weak hdr_dma1_channel6
|
||||||
.thumb_set hdr_dma_channel6, hdr_default
|
.thumb_set hdr_dma_channel6, hdr_default
|
||||||
|
|
||||||
.weak hdr_dma_channel7
|
.weak hdr_dma1_channel7
|
||||||
.thumb_set hdr_dma_channel7, hdr_default
|
.thumb_set hdr_dma_channel7, hdr_default
|
||||||
|
|
||||||
.weak hdr_adc1_2
|
.weak hdr_adc1_2
|
||||||
@ -307,3 +307,54 @@ vector_table:
|
|||||||
.weak hdr_usb_wakeup
|
.weak hdr_usb_wakeup
|
||||||
.thumb_set hdr_usb_wakeup, hdr_default
|
.thumb_set hdr_usb_wakeup, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_tim8_brk
|
||||||
|
.thumb_set hdr_tim8_brk, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_tim8_up
|
||||||
|
.thumb_set hdr_tim8_up, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_tim8_trg_com
|
||||||
|
.thumb_set hdr_tim8_trg_com, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_tim8_cc
|
||||||
|
.thumb_set hdr_tim8_cc, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_adc3
|
||||||
|
.thumb_set hdr_adc3, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_fsmc
|
||||||
|
.thumb_set hdr_fsmc, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_sdio
|
||||||
|
.thumb_set hdr_sdio, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_tim5
|
||||||
|
.thumb_set hdr_tim5, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_spi3
|
||||||
|
.thumb_set hdr_spi3, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_uart4
|
||||||
|
.thumb_set hdr_uart4, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_uart5
|
||||||
|
.thumb_set hdr_uart5, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_tim6
|
||||||
|
.thumb_set hdr_tim6, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_tim7
|
||||||
|
.thumb_set hdr_tim7, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_dma2_channel1
|
||||||
|
.thumb_set hdr_dma_channel1, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_dma2_channel2
|
||||||
|
.thumb_set hdr_dma_channel2, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_dma2_channel3
|
||||||
|
.thumb_set hdr_dma_channel3, hdr_default
|
||||||
|
|
||||||
|
.weak hdr_dma2_channel4_5
|
||||||
|
.thumb_set hdr_dma_channel4_5, hdr_default
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user