Tool/software: Code Composer Studio
I am having trouble using port interrupts on the MSP432P401R in assembly. When debugging an interrupt will be raised however, it will go into the infinite loop when an "unexpected interrupt" is received. I'd like to preface the reason that I am even trying to do this in assembly is because I am a computer engineering student who is trying to learn! I know it is not practical to do these things in assembly. Thanks ahead of time for the help!
Below is the C version of what I am trying to make in assembly and it works.
#include "msp.h"
void button_init()
{
P1->DIR &= ~BIT1; //Setup port 1.1 as input direction
P1->REN |= BIT1; //Setup port 1.1 as pull up
P1->OUT |= BIT1;
P1->IES |= BIT1; //Setup interrupt to work on falling edge
P1->IE |= BIT1; //Enable interrupt on port 1.1
P1->IFG &= ~BIT1; //Clear Flag
}
void enable_interrupts()
{
NVIC->ISER[1] = BIT3; //Enable interrupts on Port 1
}
void PORT1_IRQHandler(void)
{
if(P1->IFG & BIT1) //Check if button at P1.1 triggered interrupt
{
P2->OUT ^= BIT0; //Toggle LED
P1->IFG &= ~BIT1; //Acknowledge Interrupt on P1.1
}
}
void main(void)
{
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer
P2->DIR |= BIT0;
P2->OUT &= ~BIT0;
button_init();
enable_interrupts();
while (1)
{
}
}
Below is the assembly version of the C program above
.thumb
.data
.text
.align 2
.global main
P1DIR .field 0x40004C04,32
P1OUT .field 0x40004C02,32
P1REN .field 0x40004C06,32
P1IES .field 0x40004C18,32
P1IE .field 0x40004C1A,32
P1IFG .field 0x40004C1C,32
P2DIR .field 0x40004C05,32
P2OUT .field 0x40004C03,32
NVICISER1 .field 0xE000E104,32
button_init:
PUSH {R0, R1, LR}
LDR R1, P1DIR ;Setup button as input
LDRB R0, [R1]
BIC R0, R0, #0x02
STRB R0, [R1]
LDR R1, P1REN ;Setup button as pull up
LDRB R0, [R1]
ORR R0, R0, #0x02
STRB R0, [R1]
LDR R1, P1OUT
LDRB R0, [R1]
ORR R0, R0, #0x02
STRB R0, [R1]
LDR R1, P1IES ;Enable interrupts on button
LDRB R0, [R1]
ORR R0, R0, #0x02
STRB R0, [R1]
LDR R1, P1IE
LDRB R0, [R1]
ORR R0, R0, #0x02
STRB R0, [R1]
LDR R1, P1IFG ;Clear interrupt flag
LDRB R0, [R1]
BIC R0, R0, #0x02
STRB R0, [R1]
POP {LR, R1, R0}
BX LR
enable_interrupts:
PUSH {R0, R1, LR}
CPSIE I
LDR R1, NVICISER1 ;Enable P1 interrupts in NVIC
LDRB R0, [R1]
MOV R0, #0x08
STR R0, [R1]
POP {LR, R1, R0}
BX LR
PORT1_IRQHandler:
LDR R1, P1IFG ;Check to see if button 1 triggered interrupt
LDRB R0, [R1]
AND R0, R0, #0x02
CMP R0, #0x02
BEQ skip ;Toggle LED if button 1 triggered interrupt
LDR R2, P2OUT
LDRB R0, [R2]
EOR R0, R0, #0x01
STRB R0, [R2]
skip:
LDR R1, P1IFG ;Acknowledge interrupt
LDRB R0, [R1]
BIC R0, #0x02
STRB R0, [R1]
BX LR
main:
LDR R1, P2DIR ;Setup LED
LDRB R0, [R1]
ORR R0, R0, #0x01
STRB R0, [R1]
LDR R1, P2OUT
LDRB R0, [R1]
BIC R0, R0, #0x01
STRB R0, [R1]
BL button_init
BL enable_interrupts
loop:
B loop