how to make a handler

flyboy74
Tue Jun 19, 2018 8:54 am
OK I am trying to learn how to create my own interrupts.

I have learnt how to use registers to setup GPIO pins and to set/read them.

I now want to learn how to use registers to make interrupt. First I am trying to make an interrupt for rising edge of PA0. I think that I have setup the register properly but don’t know how to set the function that gets called when the interrupt fires.

I have some code to set the PA0 as input but will just post my code for setting up the interrupt.
uint32 *EXTI_IMR = (uint32_t *)0x400107ff;
uint32 *EXTI_RTSR = (uint32_t *)0x40010807;
uint32 *AFIO_EXTICR1 = (uint32_t *)0x40010407;

void setup() {
*EXTI_IMR = 0b00000000000000000000000000000001; //setup for pin 0
*EXTI_RTSR = 0b00000000000000000000000000000001; //setup for rising pin 0
*AFIO_EXTICR1 = 0b00000000000000000000000000000000; //setup for Port A
}


zoomx
Tue Jun 19, 2018 9:03 am
Which core?

Pito
Tue Jun 19, 2018 9:06 am
He is coreless.. He learns register level programming in C..

flyboy74
Tue Jun 19, 2018 9:07 am
I am using a blue pill STM103C

flyboy74
Tue Jun 19, 2018 9:08 am
He is coreless.. He learns register level programming in C..

Yes I would like to learn how to do it if no one had already created the fuctions for you and you just had a data shett for a new chip and had to start at the beginning :)


stevestrong
Tue Jun 19, 2018 9:23 am
Search for EXTI interrupt in Roger’s core, in files with c, cpp and S extension.

zoomx
Tue Jun 19, 2018 9:54 am
Maybe this one
https://www.programering.com/a/MDM4kzMwATg.html

dannyf
Tue Jun 19, 2018 3:23 pm
First of all, use the predefined names for the device header files. It makes the code much easier to Port to s different chip.

2nd, use the nvic-enableirq function in cmsis to put the isr in the vector table. Nvic-disableirq does the opposite.

Some examples of that can be found here: https://github.com/dannyf00/My-MCU-Libr … /STM32F1xx

Reading the datasheet is the best way to go, in my view.


flyboy74
Tue Jun 19, 2018 8:49 pm
@dannf thank you this is what I need to know.

I look at the code in your link and this is exactly what I am trying to learn.

Now I have a couple of questions

is NVIC_EnableIRQ() a standard function for C?? do I need to include anything to be able to use it??

Where can I find the vector table??

the code used NVIC_EnableIRQ(TIMx_CC_IRQn) to point to void TIM2_IRQHandler(void), I assume TIMx_CC_IRQn is in the vector table and the data sheet somewhere??? Is there somewhere I can read info on the naming of the fuction i.e why it was called TIM2_IRQHandler


dannyf
Thu Jun 21, 2018 12:39 pm
the vector table is in the start up file and the IRQs in the device header file.

flyboy74
Thu Jun 21, 2018 9:41 pm
Thanks I seem to getting much futher and a better understanding of how it all works.

I have discovered “stm32f10x.h” from ST which holds everything that I need for the blue pill.

I also understand what the GNU toolchain from Arm Cortex-M does and this is where the NVIC_EnableIRQ() comes from.

I have my code working now and will clean it up and post it for others to see :)

Thanks for everyone’s help I am slowly getting learning what I need to know :)


flyboy74
Fri Jun 22, 2018 6:08 am
Ok here is the code that I ended up with to create a interupt without using high level built Ardunio fuctions but instead low level registers.

The main loop just turns off the LED every half a second and and interupt turns it on whenever the is a rising or falling edge on PA12. I have an external pull up on the PA12

#include "stm32f10x.h"

void EXTI15_10_IRQHandler(void){
if (EXTI->PR & EXTI_PR_PR12){ //if interupt on lin 12
EXTI->PR |= EXTI_PR_PR12; //reset
GPIOC->BRR = GPIO_BRR_BR13; //Set PC13 high LED on
}
}

void waiting (int sleep){ //waste some time doing something
volatile int i,j;
for (i=0; i<sleep; ++i){
j++;
}
}

void setup() {
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; //enable port C
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //enable port A
GPIOC->CRH |= GPIO_CRH_MODE13 & ~GPIO_CRH_CNF13; //set PC13 as output PP
GPIOA->CRH &= ~GPIO_CRH_CNF12 | GPIO_CRH_CNF12_0 & ~GPIO_CRH_MODE12 ; //set PA12 as input float

AFIO->EXTICR[3] = AFIO_EXTICR4_EXTI12_PA; //enable interupt on port A
EXTI->IMR |= EXTI_IMR_MR12; //enable interupt on line 12
EXTI->RTSR |= EXTI_RTSR_TR12; //set rising trigger on line 12
EXTI->FTSR |= EXTI_FTSR_TR12; //set falling trigger on line 12

NVIC_EnableIRQ(EXTI15_10_IRQn); //set NVIC callbacks
NVIC_SetPriority(EXTI15_10_IRQn, 0); //set piroty
}

void loop() {
GPIOC->BSRR = GPIO_BSRR_BS13; //Set PC13 low
waiting(1500000);
}


dannyf
Fri Jun 22, 2018 6:42 pm
here is what I wrote – exti.c/.h: https://github.com/dannyf00/My-MCU-Libr … /STM32F1xx

An example would be:

//set LEDG
void ledg_set(void) {
IO_SET(LEDG_PORT, LEDG_PIN);
}

//PA0/BTN_PIN initialized as input with pull-up
IO_INPU(BTN_PORT, BTN_PIN);
//LEDG as output, idles low
IO_CLR(LEDG_PORT, LEDG_PIN); IO_OUT(LEDG_PORT, LEDG_PIN);

//enable exti on PA0 rising edge. User ISR is ledg_set()
exti0_init(GPIOA, EXTI_RISING);
exti0_act(pc8_set);

//enable global interrupt
ei();


Leave a Reply

Your email address will not be published. Required fields are marked *