Reputation: 11
I have written the following code to control an LED with a switch connected at B3 configured as AFIO, But it seems there is a problem with the NVIC functions, please how should they be used.
#include "stm32f10x.h"
void EXTI3_IRQHandler(void)
{
//Check if EXTI_Line0 is asserted
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
GPIOA -> ODR=0X00F0;
}
//we need to clear line pending bit manually
EXTI_ClearITPendingBit(EXTI_Line3);
}
int main()
{
// ENABLING CORRESPONDING CLOCKS
RCC->APB2ENR |= 0X000D;
RCC->APB1ENR |= 0X0001;
//CONFIGURING GPIO PORTS -- PIN 3 CONFIGURED AS AFIO PUSH/PULL AND PIN4 SET UP AS GPIO OUTPUT
GPIOA->CRL = 0X00B3B000;
GPIOB->CRL = 0X0000B000;
//PA6 IS SET AS EVENT OUTPUT PORT
AFIO->EVCR |= 0X0086;
//PB3 SET AS INPUT PORT AFIO_EXTICR1
AFIO->EXTICR[1] |= 0X1000 ;
//SELECTING RISING TRIGGERS
EXTI->RTSR = 0X0008 ;
// UNMASKING INTERRUPT SIGNAL AT EXTI3
EXTI->IMR |= 0X0008 ;
// UNMASKING EVENT SIGNAL AT EXTI6
EXTI->EMR |= 0X0040 ;
GPIOA -> ODR=0X0010;
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Upvotes: 1
Views: 5276
Reputation: 161
From what I can decipher, you want pin 3 as your interrupt line, but you set it as an OUTPUT Alt Function, according to the comment in the code. To set a pin as an exti line it needs to be set as input pull-up/down and depending on how you wired the button, you need to set rising edge trigger or falling edge trigger , and also set the internal pull up/ down resistors so that there is an actual edge change.
Example:
PIN3-->Button-->Ground
to set Pin3 as ExtI3 set pin3 as INPUT with pull up/down (NOT AFIO) since pin3 becomes low when you press the button then set edge trigger to falling edge and ODR register must pull it high when the button is not pressed. So write 1 to the corresponding ODR bit. then proceed to to the NVIC code and IRQn etc....
Upvotes: 1
Reputation: 71536
Below is a complete no library example that uses hardware interrupts, it is the timer not gpio but you should get the idea. Some folks are going to flame/bash this maybe even see how many downvotes they can recruit. They are not interested in how things work just want to have someone else make them work for them and move on. I can appreciate you wanting to understand and see this stuff. (can you find the error in the ST documentation? or perhaps it is an error in the arm documentation cut and pasted by ST into their documentation? it is not related to your problem)
I will have to dig through your question some more to see if anything jumps out. I HIGHLY recommend as shown below you take a one step at a time approach. Before enabling interrupts, using polling can you see the perpheral show an interrupt? Then can you see that interrupt pending in the NVIC (without processor interrupts enabled) and then finally if you enable the interrupt to the processor you know know that it is making it to the nvic, you can clear it, etc so the last step is your function being called. Much harder to debug if you try to do all of these things in one experiment.
flash.s
.cpu cortex-m0
.thumb
.thumb_func
.global _start
_start:
.word 0x20005000
.word reset
.word hang @ NMI
.word hang @ Hard Fault
.word hang @ MMU Fault
.word hang @ Bus Fault
.word hang @ Usage Fault
.word hang
.word hang
.word hang
.word hang
.word hang @ svcall
.word hang
.word hang
.word hang @ pendsv
.word hang @ systick
.word hang @ irq 0
.word hang @ irq 1
.word hang @ irq 2
.word hang @ irq 3
.word hang @ irq 4
.word hang @ irq 5
.word hang @ irq 6
.word hang @ irq 7
.word hang @ irq 8
.word hang @ irq 9
.word hang @ irq 10
.word hang @ irq 11
.word hang @ irq 12
.word hang @ irq 13
.word hang @ irq 14
.word hang @ irq 15
.word hang @ irq 16
.word hang @ irq 17
.word hang @ irq 18
.word hang @ irq 19
.word hang @ irq 20
.word hang @ irq 21
.word hang @ irq 22
.word hang @ irq 23
.word hang @ irq 24
.word tim1_handler @ irq 25
.word hang @ irq 26
.word hang @ irq 27
.word hang @ irq 28
.word hang @ irq 29
.thumb_func
reset:
bl notmain
b hang
.thumb_func
hang: b .
.end
putget.s
.cpu cortex-m0
.thumb
.thumb_func
.globl PUT16
PUT16:
strh r1,[r0]
bx lr
.thumb_func
.globl PUT32
PUT32:
str r1,[r0]
bx lr
.thumb_func
.globl GET32
GET32:
ldr r0,[r0]
bx lr
.thumb_func
.globl dummy
dummy:
bx lr
.end
flash.ld
MEMORY
{
rom : ORIGIN = 0x08000000, LENGTH = 0x1000
ram : ORIGIN = 0x20000000, LENGTH = 0x5000
}
SECTIONS
{
.text : { *(.text*) } > rom
.rodata : { *(.rodata*) } > rom
.bss : { *(.bss*) } > ram
}
notmain.c
//PA9 TX
//PA10 RX
void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
unsigned int GET16 ( unsigned int );
void dummy ( unsigned int );
#define USART1_BASE 0x40013800
#define USART1_SR (USART1_BASE+0x00)
#define USART1_DR (USART1_BASE+0x04)
#define USART1_BRR (USART1_BASE+0x08)
#define USART1_CR1 (USART1_BASE+0x0C)
#define USART1_CR2 (USART1_BASE+0x10)
#define USART1_CR3 (USART1_BASE+0x14)
#define USART1_GTPR (USART1_BASE+0x18)
#define GPIOA_BASE 0x40010800
#define GPIOA_CRL (GPIOA_BASE+0x00)
#define GPIOA_CRH (GPIOA_BASE+0x04)
#define GPIOA_IDR (GPIOA_BASE+0x08)
#define GPIOA_ODR (GPIOA_BASE+0x0C)
#define GPIOA_BSRR (GPIOA_BASE+0x10)
#define GPIOA_BRR (GPIOA_BASE+0x14)
#define GPIOA_LCKR (GPIOA_BASE+0x18)
#define RCC_BASE 0x40021000
#define RCC_APB2ENR (RCC_BASE+0x18)
#define RCC_CR (RCC_BASE+0x00)
#define RCC_CFGR (RCC_BASE+0x04)
#define GPIOBBASE 0x40010C00
#define RCCBASE 0x40021000
#define STK_CSR 0xE000E010
#define STK_RVR 0xE000E014
#define STK_CVR 0xE000E018
#define STK_MASK 0x00FFFFFF
#define PERIPH_BB_BASE 0x42000000
#define TIM1BASE 0x40012C00
#define TIM1_CR1 (TIM1BASE+0x00)
#define TIM1_DIER (TIM1BASE+0x0C)
#define TIM1_SR (TIM1BASE+0x10)
#define NVIC_BASE 0xE000E100
#define NVIC_ISER0 (NVIC_BASE+0x000)
#define NVIC_ISER1 (NVIC_BASE+0x004)
//...
#define NVIC_IPR18 (NVIC_BASE+0x348)
#define NVIC_IPR19 (NVIC_BASE+0x34C)
#define NVIC_IPR20 (NVIC_BASE+0x350)
#define NVIC_STIR (NVIC_BASE+0xE00)
static void clock_init ( void )
{
unsigned int ra;
//enable the external clock
ra=GET32(RCC_CR);
ra=ra|1<<16; //HSEON
PUT32(RCC_CR,ra);
//wait for HSE to settle
while(1) if(GET32(RCC_CR)&(1<<17)) break; //HSERDY
//select HSE clock
ra=GET32(RCC_CFGR);
ra&=~(0x3<<0);
ra|= (0x1<<0);
PUT32(RCC_CFGR,ra);
//wait for it
while(1) if((GET32(RCC_CFGR)&0xF)==0x5) break;
return;
}
static void uart_init ( void )
{
//assuming 8MHz clock, 115200 8N1
unsigned int ra;
ra=GET32(RCC_APB2ENR);
ra|=1<<2; //GPIOA
ra|=1<<14; //USART1
PUT32(RCC_APB2ENR,ra);
//pa9 TX alternate function output push-pull
//pa10 RX configure as input floating
ra=GET32(GPIOA_CRH);
ra&=~(0xFF0);
ra|=0x490;
PUT32(GPIOA_CRH,ra);
PUT32(USART1_CR1,0x2000);
PUT32(USART1_CR2,0x0000);
PUT32(USART1_CR3,0x0000);
//8000000/16 = 500000
//500000/115200 = 4.34
//4 and 5/16 = 4.3125
//4.3125 * 16 * 115200 = 7948800
PUT32(USART1_BRR,0x0045);
PUT32(USART1_CR1,0x200C);
}
static void uart_putc ( unsigned int c )
{
while(1)
{
if(GET32(USART1_SR)&0x80) break;
}
PUT32(USART1_DR,c);
}
static void hexstrings ( unsigned int d )
{
unsigned int rb;
unsigned int rc;
rb=32;
while(1)
{
rb-=4;
rc=(d>>rb)&0xF;
if(rc>9) rc+=0x37; else rc+=0x30;
uart_putc(rc);
if(rb==0) break;
}
uart_putc(0x20);
}
static void hexstring ( unsigned int d )
{
hexstrings(d);
uart_putc(0x0D);
uart_putc(0x0A);
}
volatile unsigned int counter;
void tim1_handler ( void )
{
counter++;
//uart_putc(0x55);
PUT32(TIM1_SR,0);
}
int notmain ( void )
{
unsigned int ra;
unsigned int rb;
unsigned int rc;
clock_init();
uart_init();
hexstring(0x12345678);
ra=GET32(RCC_APB2ENR);
ra|=1<<11; //TIM1
PUT32(RCC_APB2ENR,ra);
if(0)
{
PUT32(TIM1_CR1,0x00001);
for(rc=0;;rc++)
{
hexstring(rc);
for(ra=0;ra<1221;ra++)
{
while(1)
{
rb=GET32(TIM1_SR);
if(rb) break;
}
PUT32(TIM1_SR,0);
}
}
}
if(0)
{
PUT32(TIM1_CR1,0x00001);
PUT32(TIM1_DIER,0x00001);
while(1)
{
rb=GET32(TIM1_SR);
if(rb) break;
}
hexstring(rb);
hexstring(GET32(NVIC_ICPR0));
hexstring(GET32(NVIC_ICPR1));
hexstring(GET32(NVIC_ICPR2));
}
if(1)
{
counter=0;
PUT32(TIM1_CR1,0x00001);
PUT32(TIM1_DIER,0x00001);
PUT32(NVIC_ISER0,0x02000000);
for(rc=0;rc<10;)
{
if(counter>=1221)
{
counter=0;
hexstring(rc++);
}
}
PUT32(TIM1_CR1,0x00000);
PUT32(TIM1_DIER,0x00000);
}
return(0);
}
build, you can change the cortex-m0s to m3s if you want, m3 code is not the problem you are having
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 putget.s -o putget.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 -march=armv6-m -mthumb -mcpu=cortex-m0 -march=armv6-m -c notmain.c -o notmain.o
arm-none-eabi-ld -T flash.ld flash.o putget.o notmain.o -o notmain.elf
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy notmain.elf notmain.bin -O binary
EDIT
This uses pb8 as the input and pb9 as an output, instead of a switch that can bounce, I am driving pb9 to simulate (and control) state changes on pb8. Couldnt get pb3 to work as a generic input, just make a loop looking for pb3 to change light your led directly or use the uart to print something, and sort pb3 to ground and/or 3.3 and see if you get GPIOB IDR to show changes, I couldnt. So switched to pb8.
notmain.c
//PA9 TX
//PA10 RX
void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
unsigned int GET16 ( unsigned int );
void dummy ( unsigned int );
#define USART1_BASE 0x40013800
#define USART1_SR (USART1_BASE+0x00)
#define USART1_DR (USART1_BASE+0x04)
#define USART1_BRR (USART1_BASE+0x08)
#define USART1_CR1 (USART1_BASE+0x0C)
#define USART1_CR2 (USART1_BASE+0x10)
#define USART1_CR3 (USART1_BASE+0x14)
#define USART1_GTPR (USART1_BASE+0x18)
#define GPIOA_BASE 0x40010800
#define GPIOA_CRL (GPIOA_BASE+0x00)
#define GPIOA_CRH (GPIOA_BASE+0x04)
#define GPIOA_IDR (GPIOA_BASE+0x08)
#define GPIOA_ODR (GPIOA_BASE+0x0C)
#define GPIOA_BSRR (GPIOA_BASE+0x10)
#define GPIOA_BRR (GPIOA_BASE+0x14)
#define GPIOA_LCKR (GPIOA_BASE+0x18)
#define GPIOB_BASE 0x40010C00
#define GPIOB_CRL (GPIOB_BASE+0x00)
#define GPIOB_CRH (GPIOB_BASE+0x04)
#define GPIOB_IDR (GPIOB_BASE+0x08)
#define GPIOB_ODR (GPIOB_BASE+0x0C)
#define GPIOB_BSRR (GPIOB_BASE+0x10)
#define GPIOB_BRR (GPIOB_BASE+0x14)
#define GPIOB_LCKR (GPIOB_BASE+0x18)
#define RCC_BASE 0x40021000
#define RCC_APB2ENR (RCC_BASE+0x18)
#define RCC_CR (RCC_BASE+0x00)
#define RCC_CFGR (RCC_BASE+0x04)
#define GPIOBBASE 0x40010C00
#define RCCBASE 0x40021000
#define STK_CSR 0xE000E010
#define STK_RVR 0xE000E014
#define STK_CVR 0xE000E018
#define STK_MASK 0x00FFFFFF
#define PERIPH_BB_BASE 0x42000000
#define TIM1BASE 0x40012C00
#define TIM1_CR1 (TIM1BASE+0x00)
#define TIM1_DIER (TIM1BASE+0x0C)
#define TIM1_SR (TIM1BASE+0x10)
#define NVIC_BASE 0xE000E100
#define NVIC_ISER0 (NVIC_BASE+0x000)
#define NVIC_ISER1 (NVIC_BASE+0x004)
#define NVIC_ISER2 (NVIC_BASE+0x008)
#define NVIC_ICER0 (NVIC_BASE+0x080)
#define NVIC_ICER1 (NVIC_BASE+0x084)
#define NVIC_ICER2 (NVIC_BASE+0x088)
#define NVIC_ISPR0 (NVIC_BASE+0x100)
#define NVIC_ISPR1 (NVIC_BASE+0x104)
#define NVIC_ISPR2 (NVIC_BASE+0x108)
#define NVIC_ICPR0 (NVIC_BASE+0x180)
#define NVIC_ICPR1 (NVIC_BASE+0x184)
#define NVIC_ICPR2 (NVIC_BASE+0x188)
#define NVIC_IABR0 (NVIC_BASE+0x200)
#define NVIC_IABR1 (NVIC_BASE+0x204)
#define NVIC_IABR2 (NVIC_BASE+0x208)
#define NVIC_IPR00 (NVIC_BASE+0x300)
#define NVIC_IPR01 (NVIC_BASE+0x304)
#define NVIC_IPR02 (NVIC_BASE+0x308)
#define NVIC_IPR03 (NVIC_BASE+0x30C)
#define NVIC_IPR04 (NVIC_BASE+0x310)
#define NVIC_IPR05 (NVIC_BASE+0x314)
#define NVIC_IPR06 (NVIC_BASE+0x318)
#define NVIC_IPR07 (NVIC_BASE+0x31C)
#define NVIC_IPR08 (NVIC_BASE+0x320)
#define NVIC_IPR09 (NVIC_BASE+0x324)
#define NVIC_IPR10 (NVIC_BASE+0x328)
#define NVIC_IPR11 (NVIC_BASE+0x32C)
#define NVIC_IPR12 (NVIC_BASE+0x330)
#define NVIC_IPR13 (NVIC_BASE+0x334)
#define NVIC_IPR14 (NVIC_BASE+0x338)
#define NVIC_IPR15 (NVIC_BASE+0x33C)
#define NVIC_IPR16 (NVIC_BASE+0x340)
#define NVIC_IPR17 (NVIC_BASE+0x344)
#define NVIC_IPR18 (NVIC_BASE+0x348)
#define NVIC_IPR19 (NVIC_BASE+0x34C)
#define NVIC_IPR20 (NVIC_BASE+0x350)
#define NVIC_STIR (NVIC_BASE+0xE00)
#define EXTI_BASE 0x40010400
#define EXTI_IMR (EXTI_BASE+0x00)
#define EXTI_EMR (EXTI_BASE+0x04)
#define EXTI_RTSR (EXTI_BASE+0x08)
#define EXTI_FTSR (EXTI_BASE+0x0C)
#define EXTI_SWIER (EXTI_BASE+0x10)
#define EXTI_PR (EXTI_BASE+0x14)
#define AFIO_BASE 0x40010000
#define AFIO_EXTICR1 (AFIO_BASE+0x08)
#define AFIO_EXTICR2 (AFIO_BASE+0x0C)
#define AFIO_EXTICR3 (AFIO_BASE+0x10)
#define AFIO_EXTICR4 (AFIO_BASE+0x14)
static void clock_init ( void )
{
unsigned int ra;
//enable the external clock
ra=GET32(RCC_CR);
ra=ra|1<<16; //HSEON
PUT32(RCC_CR,ra);
//wait for HSE to settle
while(1) if(GET32(RCC_CR)&(1<<17)) break; //HSERDY
//select HSE clock
ra=GET32(RCC_CFGR);
ra&=~(0x3<<0);
ra|= (0x1<<0);
PUT32(RCC_CFGR,ra);
//wait for it
while(1) if((GET32(RCC_CFGR)&0xF)==0x5) break;
return;
}
static void uart_init ( void )
{
//assuming 8MHz clock, 115200 8N1
unsigned int ra;
ra=GET32(RCC_APB2ENR);
ra|=1<<2; //GPIOA
ra|=1<<14; //USART1
PUT32(RCC_APB2ENR,ra);
//pa9 TX alternate function output push-pull
//pa10 RX configure as input floating
ra=GET32(GPIOA_CRH);
ra&=~(0xFF0);
ra|=0x490;
PUT32(GPIOA_CRH,ra);
PUT32(USART1_CR1,0x2000);
PUT32(USART1_CR2,0x0000);
PUT32(USART1_CR3,0x0000);
//8000000/16 = 500000
//500000/115200 = 4.34
//4 and 5/16 = 4.3125
//4.3125 * 16 * 115200 = 7948800
PUT32(USART1_BRR,0x0045);
PUT32(USART1_CR1,0x200C);
}
static void uart_putc ( unsigned int c )
{
while(1)
{
if(GET32(USART1_SR)&0x80) break;
}
PUT32(USART1_DR,c);
}
static void hexstrings ( unsigned int d )
{
unsigned int rb;
unsigned int rc;
rb=32;
while(1)
{
rb-=4;
rc=(d>>rb)&0xF;
if(rc>9) rc+=0x37; else rc+=0x30;
uart_putc(rc);
if(rb==0) break;
}
uart_putc(0x20);
}
static void hexstring ( unsigned int d )
{
hexstrings(d);
uart_putc(0x0D);
uart_putc(0x0A);
}
void int_handler ( void )
{
uart_putc(0x55);
PUT32(EXTI_PR,1<<8);
PUT32(NVIC_ICPR0,1<<23);
}
static int delay ( unsigned int n )
{
unsigned int ra;
while(n--)
{
while(1)
{
ra=GET32(STK_CSR);
if(ra&(1<<16)) break;
}
}
return(0);
}
int notmain ( void )
{
unsigned int ra;
//unsigned int rb;
clock_init();
uart_init();
hexstring(0x11223344);
ra=GET32(RCC_APB2ENR);
ra|=1<<3; //GPIOB
ra|=1<<0; //AFIO
PUT32(RCC_APB2ENR,ra);
hexstring(GET32(GPIOB_CRL));
if(0)
{
//PB4 OUTPUT PB3 INPUT
ra=GET32(GPIOB_CRH);
ra&=~(0xF<<0); //PB8
ra|= (0x4<<0); //PB8 input
ra&=~(0xF<<4); //PB9
ra|= (0x1<<4); //PB9 output
PUT32(GPIOB_CRH,ra);
hexstring(GET32(GPIOB_IDR));
PUT32(GPIOB_BSRR,(1<<9)<< 0);
hexstring(GET32(GPIOB_IDR));
PUT32(GPIOB_BSRR,(1<<9)<<16);
hexstring(GET32(GPIOB_IDR));
}
if(0)
{
ra=GET32(GPIOB_CRH);
ra&=~(0xF<<0); //PB8
ra|= (0x4<<0); //PB8 input
ra&=~(0xF<<4); //PB9
ra|= (0x1<<4); //PB9 output
PUT32(GPIOB_CRH,ra);
hexstring(GET32(GPIOB_IDR)&(1<<8));
PUT32(GPIOB_BSRR,(1<<9)<< 0);
hexstring(GET32(GPIOB_IDR)&(1<<8));
PUT32(AFIO_EXTICR3,1<<0);
PUT32(EXTI_RTSR,1<<8);
//PUT32(EXTI_FTSR,1<<8);
//PUT32(EXTI_SWIER,1<<8);
PUT32(EXTI_IMR,1<<8);
//PUT32(EXTI_EMR,1<<8);
PUT32(GPIOB_BSRR,(1<<9)<<16);
hexstring(GET32(GPIOB_IDR)&(1<<8));
PUT32(GPIOB_BSRR,(1<<9)<< 0);
hexstring(GET32(GPIOB_IDR)&(1<<8));
hexstring(0xaabbccde);
//hexstring(GET32(EXTI_SWIER));
hexstring(GET32(EXTI_PR));
hexstring(GET32(NVIC_ICPR0));
hexstring(GET32(NVIC_ICPR1));
hexstring(GET32(NVIC_ICPR2));
hexstring(0xaabbccdf);
PUT32(EXTI_PR,1<<8);
hexstring(GET32(EXTI_PR));
hexstring(GET32(NVIC_ICPR0));
hexstring(GET32(NVIC_ICPR1));
hexstring(GET32(NVIC_ICPR2));
hexstring(0xaabbccef);
PUT32(NVIC_ICPR0,1<<23);
hexstring(GET32(EXTI_PR));
hexstring(GET32(NVIC_ICPR0));
hexstring(GET32(NVIC_ICPR1));
hexstring(GET32(NVIC_ICPR2));
}
ra=GET32(GPIOB_CRH);
ra&=~(0xF<<0); //PB8
ra|= (0x4<<0); //PB8 input
ra&=~(0xF<<4); //PB9
ra|= (0x1<<4); //PB9 output
PUT32(GPIOB_CRH,ra);
//hexstring(GET32(GPIOB_IDR)&(1<<8));
//PUT32(GPIOB_BSRR,(1<<9)<< 0);
//hexstring(GET32(GPIOB_IDR)&(1<<8));
PUT32(AFIO_EXTICR3,1<<0);
PUT32(EXTI_RTSR,1<<8);
//PUT32(EXTI_FTSR,1<<8);
//PUT32(EXTI_SWIER,1<<8);
PUT32(EXTI_IMR,1<<8);
//PUT32(EXTI_EMR,1<<8);
PUT32(NVIC_ISER0,0x00800000);
PUT32(STK_CSR,4);
PUT32(STK_RVR,1000000-1);
PUT32(STK_CVR,0x00000000);
PUT32(STK_CSR,5);
while(1)
{
PUT32(GPIOB_BSRR,(1<<9)<<16);
delay(8);
PUT32(GPIOB_BSRR,(1<<9)<< 0);
delay(8);
}
return(0);
}
I found it used interrupt 23.
8000098: 080000bf
800009c: 0800014d <- points at interrupt handler
80000a0: 080000bf
and that matches the documentation for EXTI lines 9 to 5 (search for EXTI9_5 and or 009C in the vector table or 0x0000_009C).
It does not seem to care if the pb is configured as an AFIO output (0xB) or a floating input (0x4). So I dont think that is your problem.
This array of volatile pointers is even worse than just using volatile pointers:
AFIO->EXTICR[1]
I am wondering if that really uses EXTCR2 0x4001000C instead of EXTCR1 which is what you want 0x40010008. I would make a one line program
AFIO->EXTICR[1]=7
then disassemble it and see if they are producing a store to 0x40010008, if not then there is your problem.
From what I saw you dont need to mess with EMR and despite the drawing (another documentation bug?) you dont need to set the SWIER in order to get the signal to pass through to the PR. I only needed the registers shown above to get the PR to reflect the edge detect on the input. And from there then the NVIC could see it and then I could setup a handler.
I used the systick timer to drive my pb9 output every second, causing the interrupt every other second as I am only watching for one of the edges. If you have a switch you wont need any of that obviously.
Upvotes: 4