This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430FR6989: Multiple Interrupts and UART

Part Number: MSP430FR6989

Tool/software: Code Composer Studio

Alright I am having another multiple interrupt problem similar to the previous question, but this time with UARTs.

So this is the code I have right now. I am definitely sure the code for the master works. It is the slave code which is messing up (and the slave has other interrupts there as well). I am including both the slave and the master code here. (the simplified versions).  

I think it is one of the Mainloops which is creating the problem in the slave code. So I have an interrupt set up for ADC signals (which utilizes Mainloop) and interrupt set up for UART (which uses MainloopU). I think the MainloopU is never executed but how else to incorporate UART interrupt and ADC interrupt at the same time? Or is it another issue?

Also how do we set up the logistics for setting up UART? So does the master code and the slave code go in separate projects or in the same project?

Thanks in advance,

SLAVE CODE

;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file
;-------------------------------------------------------------------------------
;--- external references -------------------------------------------------------
            .ref initGPIO
            .ref initClocks
            .ref myLCD_init
            .ref myLCD_showChar
            .ref myLCD_displayNumber
            .def    RESET                   ; Export program entry-point to
                                            ; make it known to linker.
;-------------------------------------------------------------------------------
            .global _main
            .global __STACK_END
            .sect   .stack                  ; Make stack linker segment ?known?

            .data
LISTI: .word 0x0000,0x0001,0x0002,0x0001,0x0003,0x0000,0x0001,0x0004,0x0000,0x0001,0x0005,0x0000          ; first element initially 0000
VAR1: .space 2
VAR2: .space 2
VARX: .space 2
VARY: .space 2
VARZ: .space 2
VARS: .space 2
VARLA: .space 2
VARIND: .space 2
VARSCR: .space 2
VARSHK: .space 2
VAREXT: .space 2

      .bss Result, 2


            .text                           ; Assemble to Flash memory
            .retain                         ; Ensure current section gets linked
            .retainrefs

_main
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT

         call   #initGPIO
     
         call   #myLCD_init

                           bic.b #BIT3,&P3OUT
                           bic.b #BIT6,&P2OUT
                           bic.b #BIT6,&P3OUT
SetUpBoosterLed            bis.b #BIT6,&P3DIR
                           bis.b #BIT6,&P2DIR
                           bic.b #BIT3,&P3OUT
                           bic.b #BIT6,&P2OUT
                           bic.b #BIT6,&P3OUT


SetupGPIO   bic.b   #BIT0,&P1OUT            ; Clear LED to start
            bis.b   #BIT0,&P1DIR            ; P1.0 output

            bic.b   #BIT7,&P9OUT            ; Clear LED to start
            bis.b   #BIT7,&P9DIR            ; P1.0 output

            bis.b   #BIT0+BIT1,&P2SEL0      ; USCI_A0 UART operation
            bic.b   #BIT0+BIT1,&P2SEL1

            bic.b   #BIT0,&P3DIR            ; Set P3.0 as an input button with pull-up resistor
            bis.b   #BIT0,&P3REN
            bis.b   #BIT0,&P3OUT

            bic.b   #BIT1,&P3DIR            ; Set P3.1 as an input button with pull-up resistor
            bis.b   #BIT1,&P3REN
            bis.b   #BIT1,&P3OUT


SetupP9     bis.b   #BIT2,&P9SEL0           ;
            bis.b   #BIT2,&P9SEL1           ;


            mov.w   #0x0002, R10            ;
            mov.w   #0x0000, R8
            bis.b #BIT7, &P2DIR              ;100 600 200  (Bad Noise)

SetupP8     bis.b #BIT7,&P8SEL0
            bis.b #BIT7,&P8SEL1

            bis.b #BIT6,&P8SEL0
            bis.b #BIT6,&P8SEL1

            mov.w #0,&VARSCR

            mov.w #0x0000,&VARIND
            mov.w #0,R5

UnlockGPIO  bic.w   #LOCKLPM5,&PM5CTL0      ; Disable the GPIO power-on default
                                            ; high-impedance mode to activate
                                            ; previously configured port setting
ButnInterrupt
            bis.b   #BIT0,&P3IES            ; Configure P3.0 as a high-to-low interrupt
            bic.b   #BIT0,&P3IFG
            bis.b   #BIT0,&P3IE

            bis.b   #BIT1,&P3IES            ; Configure P3.1 as a high-to-low interrupt
            bic.b   #BIT1,&P3IFG
            bis.b   #BIT1,&P3IE


SetupADC12  mov.w   #ADC12SHT0_2+ADC12ON+ADC12MSC,&ADC12CTL0 ; 16x
            bis.w   #ADC12SHP+ADC12CONSEQ_1,&ADC12CTL1    ; ADCCLK = MODOSC; sampling timer
            bis.w   #ADC12RES_2,&ADC12CTL2  ; 12-bit conversion results

            bis.w   #ADC12INCH_10,&ADC12MCTL0; A10 ADC input select; Vref=AVCC Joystick hor
            bis.w   #ADC12INCH_4,&ADC12MCTL1 ; A4 Joystick Vertical

            bis.w   #ADC12INCH_5+ADC12EOS,&ADC12MCTL2 ; A5 Accelerometer Z

            bis.w   #ADC12IE2,&ADC12IER0    ; Enable ADC conv complete interrupt
SetUpUART
            mov.w   #UCSWRST,&UCA0CTLW0     ; Put eUSCI in reset
            bis.w   #UCSSEL__SMCLK,&UCA0CTLW0 ; CLK = SMCLK
            mov.b   #8, &UCA0BR0            ; 1000000/115200 = 8.68
            bis.w   #0xD600,&UCA0MCTLW      ; 1000000/115200 - INT(1000000/115200)=0.68
                                            ; UCBRSx value = 0xD6 (See UG)
            clr.b   &UCA0BR1
            bic.b   #UCSWRST,&UCA0CTL1      ; release from reset
            bis.w   #UCRXIE,&UCA0IE         ; Enable USCI_A0 RX interrupt

                     

Mainloop    mov.w   #35000,R15               ; Delay ~5000 cycles between conversions
L1          dec.w   R15                     ; Decrement R15
            jnz     L1                      ; Delay over?
            bis.w   #ADC12ENC+ADC12SC,&ADC12CTL0 ; Start sampling/conversion
            nop                             ;
            bis.w   #LPM0+GIE,SR            ; Enter LPM0 w/ interrupt
            nop                             ; for debug
            jmp     Mainloop                ; Again
            nop
MainloopU   bit.w   #UCTXIFG,&UCA0IFG
            jeq     MainloopU
            mov.w   &VARSCR,&TXData
            mov.w   &TXData,&UCA0TXBUF
            nop                             ;
            bis.w   #LPM0+GIE,SR            ; Enter LPM0 w/ interrupt
            nop                             ; for debug
            jmp     Mainloop
            nop
NeedHere
;-------------------------------------------------------------------------------
ADC12_ISR;  ADC12 interrupt service routine
;-------------------------------------------------------------------------------
            add.w   &ADC12IV,PC             ; add offset to PC
            reti                            ; Vector  0:  No interrupt
            reti                            ; Vector  2:  ADC12MEMx Overflow
            reti                            ; Vector  4:  Conversion time overflow
            reti                            ; Vector  6:  ADC12HI
            reti                            ; Vector  8:  ADC12LO
            reti                            ; Vector 10:  ADC12IN
            jmp     MEM0                    ; Vector 12:  ADC12MEM0 Interrupt
            jmp     MEM1                    ; Vector 14:  ADC12MEM1
            jmp     MEM2                    ; Vector 16:  ADC12MEM2
            reti                            ; Vector 18:  ADC12MEM3
            reti                            ; Vector 20:  ADC12MEM4
            reti                            ; Vector 22:  ADC12MEM5
            reti                            ; Vector 24:  ADC12MEM6
            reti                            ; Vector 26:  ADC12MEM7
            reti                            ; Vector 28:  ADC12MEM8
            reti                            ; Vector 30:  ADC12MEM9
            reti                            ; Vector 32:  ADC12MEM10
            reti                            ; Vector 34:  ADC12MEM11
            reti                            ; Vector 36:  ADC12MEM12
            reti                            ; Vector 38:  ADC12MEM13
            reti                            ; Vector 40:  ADC12MEM14
            reti                            ; Vector 42:  ADC12MEM15
            reti                            ; Vector 44:  ADC12MEM16
            reti                            ; Vector 46:  ADC12MEM17
            reti                            ; Vector 48:  ADC12MEM18
            reti                            ; Vector 50:  ADC12MEM19
            reti                            ; Vector 52:  ADC12MEM20
            reti                            ; Vector 54:  ADC12MEM21
            reti                            ; Vector 56:  ADC12MEM22
            reti                            ; Vector 58:  ADC12MEM23
            reti                            ; Vector 60:  ADC12MEM24
            reti                            ; Vector 62:  ADC12MEM25
            reti                            ; Vector 64:  ADC12MEM26
            reti                            ; Vector 66:  ADC12MEM27
            reti                            ; Vector 68:  ADC12MEM28
            reti                            ; Vector 70:  ADC12MEM29
            reti                            ; Vector 72:  ADC12MEM30
            reti                            ; Vector 74:  ADC12MEM31
            reti                            ; Vector 76:  ADC12RDY

MEM2
            mov.w   &ADC12MEM2,&VARZ
            mov.w   &ADC12MEM1, R9
            mov.w   &ADC12MEM0, R14
            ;DO STUFF

ExitLPM0    bic.w   #LPM0,0(SP)             ; Exit
            reti



MEM0                   ; Clear LED as default
            bic.w   #LPM0,0(SP)
            reti
MEM1                   ; Clear LED as default
            bic.w   #LPM0,0(SP)
            reti
;-------------------------------------------------------------------------------
PORT3_0_ISR;    P3.0 Interrupt Service Routine
;-------------------------------------------------------------------------------


            bit.b #BIT1, &P3IFG
            jnz Pin3_1Stuff

            sub.w #4, SP               ; DEBOUNCING ACCOUNTED
            mov.w #5000, 0(SP)
            clr.w 2(SP)



testloop    bit.b #BIT0, &P3IN
            jnz   not_down
            inc.w 2(SP)
not_down    dec.w 0(SP)
            jnz   testloop

;---------------LOOP COMPLETED ---------------

            cmp.w #800, 2(SP)
            jl    exit
            bic.b   #BIT0, &P3IFG
            ;DO STUFF
;--------------EXIT ISR ----------------------
exit:       clr.b &P3IFG
            add.w #4, SP
            jmp SKipthere
Pin3_1Stuff
            sub.w #4, SP                 ; Accounting for Debouncing of switches
            mov.w #5000, 0(SP)
            clr.w 2(SP)

testloop2    bit.b #BIT1, &P3IN
             jnz   not_down2
             inc.w 2(SP)
not_down2   dec.w 0(SP)
            jnz   testloop2

;---------------LOOP COMPLETED ---------------


          cmp.w #800, 2(SP)
          jl    exit2
          bic.b #BIT1, &P3IFG
           
          ; DO STUFF

exit2:      clr.b &P3IFG
            add.w #4, SP
SKipthere
            reti
;------------------------------------------------------------------------------
USCI_A0_ISR;    USCI A0 Receive/Transmit Interrupt Service Routine
;------------------------------------------------------------------------------
            add.w   &UCA0IV,PC              ; add offset to PC
            reti                            ; Vector 0: No interrupts
            jmp     Receive                 ; Vector 2: USCI UCRXIFG
            reti                            ; Vector 4: USCI UCTXIFG
            reti                            ; Vector 6: USCI UCSTTIFG
            reti                            ; Vector 8: USCI UCTXCPTIFG
Receive     mov.w   &UCA0RXBUF,&RXData       ; Read buffer
            ; As Slave, do nothing with received data from Master
            bic.w   #LPM0,0(SP)             ; Exit LPM0 on reti
            reti
TrapCPU     jmp     TrapCPU                 ; Trap CPU
            reti



;------------------------------------------------------------------------------
;           Interrupt Vectors
;------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET                   ;
            .sect   ADC12_VECTOR            ; ADC12 Vector
            .short  ADC12_ISR               ;
            .sect   ".int31"                ;Button Interrupt
            .short  PORT3_0_ISR
            .sect   USCI_A0_VECTOR
            .short  USCI_A0_ISR
            .end
;-------------------------------------------------------THE END OF SLAVE--------------------------------------------------------------------------------------------------------------------------------------------

;MASTER CODE UART
;MASTER (a MSP430FR6989) CONNECTED TO TWO Slaves (SLAVE_1 and SLAVE_2)
;Connections

;Slave_1 P2.0---->Master P2.1
;Slave_1 P2.1 <-----Master P2.0
;GND<---->GND


;GND<---->GND
;-------------------------------------------------------------------------------
.cdecls C,LIST,"msp430.h" ; Include device header file
;-------------------------------------------------------------------------------
.ref initGPIO
.ref initClocks
.ref myLCD_init
.ref myLCD_showChar
.ref myLCD_displayNumber
.def RESET ; Export program entry-point to
; make it known to linker.
;-------------------------------------------------------------------------------
RXData1 .set R5
RXData2 .set R7
TXData .set R6
;-------------------------------------------------------------------------------
.global _main
.global __STACK_END
.sect .stack ; Make stack linker segment ?known?
.data
.bss Result, 2
.text ; Assemble to Flash memory
.retain ; Ensure current section gets linked
.retainrefs

_main
RESET mov.w #__STACK_END,SP ; Initialize stackpointer
StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop watchdog timer

call #initGPIO
call #myLCD_init

mov.w #'A', R12
mov.w #1, R13
call #myLCD_showChar

mov.w #2, R13
mov.w #'0', R12
call #myLCD_showChar

mov.w #3, R13
mov.w #'0', R12
call #myLCD_showChar

mov.w #4, R13
mov.w #'B', R12
call #myLCD_showChar

mov.w #5, R13
mov.w #'0', R12
call #myLCD_showChar

mov.w #6, R13
mov.w #'0', R12
call #myLCD_showChar

mov.w &Result, R15


SetupGPIO
SetUpP2
bis.b #BIT0+BIT1,&P2SEL0 ; USCI_A0 UART operation
bic.b #BIT0+BIT1,&P2SEL1
SetUpP3
;bis.b #BIT5+BIT4,&P3SEL0 ; USCI_A1 UART operation
;bic.b #BIT5+BIT4,&P3SEL1
UnlockGPIO bic.w #LOCKLPM5,&PM5CTL0 ; Disable the GPIO power-on default
; high-impedance mode to activate
; previously configured port settings

SetupUART
mov.w #UCSWRST,&UCA0CTLW0 ; Put eUSCI in reset
; mov.w #UCSWRST,&UCA1CTLW0

bis.w #UCSSEL__SMCLK,&UCA0CTLW0 ; CLK = SMCLK
;bis.w #UCSSEL__SMCLK,&UCA1CTLW0 ; CLK = SMCLK

mov.b #8, &UCA0BR0 ; 1000000/115200 = 8.68
; mov.b #8,&UCA1BR0
bis.w #0xD600,&UCA0MCTLW ; 1000000/115200 - INT(1000000/115200)=0.68
; UCBRSx value = 0xD6 (See UG)
;bis.w #0xD600,&UCA1MCTLW

clr.b &UCA0BR1
;clr.b &UCA1BR1

bic.b #UCSWRST,&UCA0CTL1 ; release from reset
;bic.b #UCSWRST,&UCA1CTL1

bis.w #UCRXIE,&UCA0IE ; Enable USCI_A0 RX interrupt
; bis.w #UCRXIE,&UCA1IE ; Enable USCI_A1 RX interrupt

mov.w #0,RXData1 ; RXData1 = 0
; mov.w #0,RXData2 ; RXData1 = 0

mov.w #1,TXData ; TXData = 1
Mainloop bit.w #UCTXIFG,&UCA0IFG
jeq Mainloop
mov.w TXData,&UCA0TXBUF ; Load data onto buffer
nop ;
bis.w #LPM0+GIE,SR ; Enter LPM0, interrupts enabled
nop ; For debugger
jmp Mainloop
;Mainloop2 bit.w #UCTXIFG,&UCA1IFG
; jeq Mainloop2
; mov.w TXData,&UCA1TXBUF ; Load data onto buffer
; nop ;
; bis.w #LPM0+GIE,SR ; Enter LPM0, interrupts enabled
; nop ; For debugger
; jmp Mainloop2


;------------------------------------------------------------------------------
USCI_A0_ISR; USCI A0 Receive/Transmit Interrupt Service Routine
;------------------------------------------------------------------------------
add.w &UCA0IV,PC ; add offset to PC
reti ; Vector 0: No interrupts
jmp Receive ; Vector 2: USCI UCRXIFG
reti ; Vector 4: USCI UCTXIFG
reti ; Vector 6: USCI UCSTTIFG
reti ; Vector 8: USCI UCTXCPTIFG
Receive mov.w &UCA0RXBUF,RXData1 ; Read buffer

mov.w #'A', R12
mov.w #1, R13
call #myLCD_showChar

mov.w #2, R13
mov.w #'0', R12
call #myLCD_showChar

mov.w #3, R13
mov.w #'1', R12
call #myLCD_showChar

mov.w #4, R13
mov.w #'B', R12
call #myLCD_showChar

mov.w #5, R13
mov.w #'0', R12
call #myLCD_showChar

mov.w #6, R13
mov.w #'1', R12
call #myLCD_showChar

mov.w &Result, R15

;Do something with RXData1
bic.w #LPM0,0(SP) ; Exit LPM0 on reti
reti
TrapCPU jmp TrapCPU ; Trap CPU
reti
;------------------------------------------------------------------------------
;USCI_A1_ISR; USCI A1 Receive/Transmit Interrupt Service Routine
;------------------------------------------------------------------------------
; add.w &UCA1IV,PC ; add offset to PC
; reti ; Vector 0: No interrupts
; jmp Receive2 ; Vector 2: USCI UCRXIFG
; reti ; Vector 4: USCI UCTXIFG
; reti ; Vector 6: USCI UCSTTIFG
; reti ; Vector 8: USCI UCTXCPTIFG
;Receive2 mov.w &UCA1RXBUF,RXData2 ; Read buffer
; Do something with the RXData2
; bic.w #LPM0,0(SP) ; Exit LPM0 on reti
; reti
;TrapCPU2 jmp TrapCPU2 ; Trap CPU
; reti

;------------------------------------------------------------------------------
; Interrupt Vectors
;------------------------------------------------------------------------------
.sect ".reset" ; MSP430 RESET Vector
.short RESET ;
.sect USCI_A0_VECTOR ; USCI A0 Receive/Transmit Vector
.short USCI_A0_ISR
; .sect USCI_A1_VECTOR ; USCI A1 Receive/Transmit Vector
; .short USCI_A1_ISR
.end

  • The short answer is that, scanning forward from MainLoop, there are only backwards jumps, so there's no way to get to MainLoopU from there. So remove the (first) " jmp MainLoop".

    Then there's the second LPM0, but there's no wakeup source -- the ADC is long finished, and who knows when you'll get an Rx byte? So remove that as well.

    I think that will give you a running MainLoop; then you need to figure out how your game is played.
    --------------------------
    Last I worked with IAR, a Workspace was a collection of loosely-related source files, and Projects collected subsets (usually overlapping) of those files. A Project equalled a loadable image. Within that structure, the master, slave, and shared files would live in the Workspace, and master and slave would be different Projects. A shared file would be in both Projects.
    --------------------------
    Unrelated: These source files are getting big enough that you should probably be attaching rather than pasting.
  • Thanks a lot for all your help... that solved it. We are nearing the end of completing the game thanks to you and some other folks!!

**Attention** This is a public forum