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.

IAR Workbench (IAR Assembler)- MSP430

Hi all,

I am facing a small problem that whenever I debug my program, the Program Counter goes to 0xFFFE.

Maybe it is due to some incorrect selection of option.

I then take the PC to 0x2100 manually for stepwise execution.

Thanks

  • sunil sharma said:

    Hi all,

    I am facing a small problem that whenever I debug my program, the Program Counter goes to 0xFFFE.

    Is this when you first load the program into the target?  And your title suggested you are implementing an assembly only project, correct?

    The address 0xFFFE is the reset vector of the device.  I fully expect the first thing the device to do is go to the reset vector.  In your program, you should load the starting point of your program at this location.  The MSP430 CPU will use the value at the location 0xFFFE as an address and branch to it.

    Perhaps your 0x2100 location?

  • sunil sharma said:
    whenever I debug my program, the Program Counter goes to 0xFFFE.

    This is usually an indication that the CPU has fetched a vector to an ISR form teh vector table, but there was no ISR assigned to thsi event. Then the vector table contains 0xffff, which results in a jump to 0xfffe (LSB ignored).
    This includes the reset vector (in case you're writing an assembly program and didn't set the reset vector to the start of your program - for C programs, the compiler and linker include the proper code for the reset vector)

  •  

    Hi Michael,

    Thanks for your advice. But can you pls tell me how to rectify it and get the PC to 2100 initially (code placed)

    I am relatively new to MSP430 and IAR workbench

    Using the example code of TI I have written a program for transmitting 2 bytes using SPI between MSP430 and DSP (SS sgl routed via 1:8 multiplexer)

    However the program is not working as expected

    -On reaching the USCIA0TX_ISR by stepwise execution the pgm is continuously running and only one byte reaces TXBUF. Also the TXIFG flag remains set even on transferring one byte in TXBUF.

    -Is it necessary to use FLL/DCO as in example code

    -Is it necessary to reset the slave after every transmission or a delay shall suffice

     

    #include  <msp430xG46x.h>

    ;-------------------------------------------------------------------------------

                RSEG    CSTACK                  ; Define stack segment

    ;-------------------------------------------------------------------------------

                RSEG    CODE                    ; Assemble to Flash memory

    ;-------------------------------------------------------------------------------

                RSEG    INFO                  ; Assemble to INFORMATION MEMORY

    ;-----------------------------------------------------------------------------

    RESET       mov.w    #SFE(CSTACK),SP    ;#02100h,SP;   ; Initialize stackpointer       

    StopWDT     mov.w   #WDTPW+WDTHOLD+WDTNMI+WDTTMSEL+WDTSSEL,&WDTCTL  ; Stop WDT

    setupSVS    mov.b   #018h,&SVSCTL            ;Vth = 1.9V

    setupRTC    mov.b   #30h,&RTCCTL

                bis.b   #RTCBCD,&RTCCTL

    ;----------------------------------------------------------------

    ;SETUP MSP430 FOR SPI-McBSP INTERFACE

    ;-----------------------------------------------------------------

    SetupP7     bis.b   #0Eh,&P7SEL             ; P7.3,2,1 option select

     

    SetupSPI     bis.b   #UCMST+UCSYNC+UCCKPL+UCMSB,&UCA0CTL0;3-pin, 8-bit SPI master

                bis.b   #UCSSEL_2,&UCA0CTL1     ; SMCLK

                mov.b   #02h,&UCA0BR0           ; /2

                clr.b   &UCA0BR1                ;

                clr.b   &UCA0MCTL               ; No modulation

                bic.b   #UCSWRST,&UCA0CTL1      ; **Initialize USCI state machine**

                bis.b   #UCA0RXIE,&IE2          ; Enable USCI_A0 RX interrupt

                  bis.b   #UCA0TXIE,&IE2          ; Enable USCI_A0 TX interrupt

    ;----------------------------------------------------------------

    ;CONFIGURE PORT8 FOR SELECTING THE SLAVE VIA 1:8 MUX-DEMUX

    ;----------------------------------------------------------------

    SetupP8     mov.b   #070h,&P8DIR            ;CONFIGURE THE PORT FOR S0,S1,S2

                mov.b   #00h,&P8SEL

     

                mov.b   #000h,&P8OUT            ; SELECT DSP1 of 4 DSPs

     

                bic.b   #000h,&P7OUT;MAKE SS LOW BY SETTING P7.0 LOW - will require to out 0 from 7.1

     

     

     

    ;SetupP5     mov.b   #04h,&P5OUT             ; P5 setup for LED and slave reset  ;    -Is it necessary to reset the slave after every transmission or a delay shall suffice

               ;bis.b   #06h,&P5DIR             ;

     

     

                ;bic.b   #04h,&P5OUT             ; Now with SPI signals initialized,

                ;bis.b   #04h,&P5OUT             ; reset slave

                ;mov.w   #50,R15                 ; Wait for slave to initialize       

    ;waitForSlv dec.w   R15                     ;

                ;jnz     waitForSlv

     

                mov.b   #001h,R6                 ; Initialize Tx data values

     

    Mainloop   mov.b   R6,&UCA0TXBUF           ; Transmit first character

               bis.b   #LPM0+GIE,SR            ; CPU off, enable interrupts

               ;nop                             ; Required for debugger only

    ;------------------------------------------------------------------------------

    USCIA0TX_ISR;       TRANSMISSION THRU SPI       ;On reaching the USCIA0TX_ISR by stepwise execution the pgm is continuously running and only one byte reaces TXBUF. Also the TXIFG flag remains set even on transferring one byte in TXBUF.

    ;------------------------------------------------------------------------------

    TX1     bit.b #UCA0TXIFG,&IFG2    ;TX Buffer ready

       jz TX1

     

                mov.w   #30,R15                 ; Add time between transmissions to

    cycleDelay  dec.w   R15                     ; make sure slave can keep up

               jnz     cycleDelay

     

    TX2         inc.b   R6                      ; Increment master value

                mov.b   R6,&UCA0TXBUF           ; Send next value

     

        reti                            ; Exit ISR                                                                                                                     

    ;------------------------------------------------------------------------------

                COMMON  INTVEC                  ; Interrupt Vectors

    ;------------------------------------------------------------------------------

                ORG     USCIAB0TX_VECTOR        ; USCI_A0 I2C Data Int Vector

                DW      USCIA0TX_ISR

                ORG     RESET_VECTOR            ; MSP430 RESET Vector

                DW      RESET                   ;

                END

     

  • sunil sharma said:
                bis.b   #UCA0RXIE,&IE2          ; Enable USCI_A0 RX interrupt
                  bis.b   #UCA0TXIE,&IE2          ; Enable USCI_A0 TX interrupt

    Here you enable RX and TX interrupt

    sunil sharma said:
                ORG     USCIAB0TX_VECTOR        ; USCI_A0 I2C Data Int Vector
                DW      USCIA0TX_ISR
                ORG     RESET_VECTOR            ; MSP430 RESET Vector
                DW      RESET     

    And here you define reset and TX vector, but not RX vector. So as soon as something is received, the processor jumps into the void.

    Note that on 5x family devices, the USCIs have a common RX and TX vector for each A or B submodule, but on 2x and 4x devices, RX and TX have a separate vector, shared between A and B module.

     

  • Thanks Michael.....for your help and advice.

    Also I would like to ask if - 

    -Is it necessary to use FLL/DCO as in example code.

    -Is it necessary to reset the slave after every transmission or a delay shall suffice between transmissions.

    -Also looking at the code, can you please tell why PC is going to 0xFFFE initially instead of 0x2100.

  • sunil sharma said:

    -Also looking at the code, can you please tell why PC is going to 0xFFFE initially instead of 0x2100.

     

    I believe this was explained.  0xFFFE is the reset vector.  Upon release of reset, the CPU will fetch the contents at this location (ie. 0xFFFE) and use it as a branch address.  Therefore, I would expect the contents of 0xFFFE to be 0x2100.  Is this what you see in the debugger memory window?

  • sunil sharma said:
    -Is it necessary to use FLL/DCO as in example code.

    No. But it provides a mroe or less table frequency. Without the FLL, the DCO frequency can be almost anything in a wider range. However, you can as well set up an external crystal and get your CPU and SMCLK/ACLK frequency from it, Then you don't need the DCO at all.

    sunil sharma said:
    -Is it necessary to reset the slave after every transmission or a delay shall suffice between transmissions.

    The hardware does not need a reset. But depending on the high-level protocol between teh two devices, it might be necessary to de-assert and assert a chip-select signal between two independent transmissions. Also, this signal is usually required for synchronization, as the SPI itself doesn't carry any information about when a byte begins. So usually, the hardware is initialized (reset) when a low-going edge on thsi chip select signal is detected.

    Between any CS transition and teh next operation, a small delay might be necessary (to allow the other side to set up for the next communication block).

    sunil sharma said:
    -Also looking at the code, can you please tell why PC is going to 0xFFFE initially instead of 0x2100.

    Because nobody tells the processor to do so.

    When an interrupt is triggered (this includes the reset), the CPU reads an address word from the vector table that is associated with the ISR to execute. The CPU is not jumping to 0xfffe on a reset, it is looking up at 0xfffe where to jump to.
    Same for any interrupt event. You enabled two interrupt events which each have its own vector. Yout you only defined one ISR and wrot eonly one address to the proper locaiton in the vector table. So for the second event (RXIFG), the CPU finds the default flash content of 0xffff in teh ector table, whcih results in a jump to 0xfffe (LSB is always 0 in the program counter).

    One more thing: you asked why the TXIFG bit is always 1: it isn't. But it is when you do single-stepping. because the USCI does double buffering. When writing to TXBUF, the data is immediately moved to the output shift register and TXBUF is free again for a second byte. During single-stepping, you are so slow, that the current byte is send and the one in TXBUF is move to output and sent and TXIFG is set again long before the single step is complete. JTAG access is slooooow and takes many clock cycles during which the normal hardware normally continues to work.

  • The contents of the location0xFFFE show FFFF(in fact its all FFs from 0xFF00 onwards).

    That is why it is branching to 0xFFFE. 

    Do I have to change the content. of this location ......But it shows that it is ROM and some device file will have to be changed for that......

  • Got the point about DCO & FLL and the reset requirement.

    I disabled RXIFG first, but the pgm still went into a void on reaching UCA0TX_ISR.

    Then I disabled GIE as well . Only Then the program stopped going into a void. However I read in the userguide that a NMI is enabled only when both GIE and individual bit are set.

    <<

    When an interrupt is triggered (this includes the reset), the CPU reads an address word from the vector table that is associated with the ISR to execute. The CPU is not jumping to 0xfffe on a reset, it is looking up at 0xfffe where to jump to.

    Same for any interrupt event. You enabled two interrupt events which each have its own vector. Yout you only defined one ISR and wrot eonly one address to the proper locaiton in the vector table. So for the second event (RXIFG), the CPU finds the default flash content of 0xffff in teh ector table, whcih results in a jump to 0xfffe (LSB is always 0 in the program counter).

    The value I watched at the 0xFFFE in memory while debugging is FFFF. Is that why  the pgm is branching to this address on reset .....Do I have to change this....

    Now that there are no enabled interrupts, and also no int without being defined in the IVT, is this happening because of an interrupt?

     

    And Thanks a ton for your time and patience....

  • sunil sharma said:
    The value I watched at the 0xFFFE in memory while debugging is FFFF.

    Hmmm, it shouldn't. If it is FFFF, it doesn't execute any of your code at all.
    I'm a bit surprised that the jump is taken, as the bootstrap loader should detect this, take it for an empty MSP and send the MSP to sleep instead of trying to jump to 0xfffe.

    This code should normally define the vectors:

    sunil sharma said:
    ;------------------------------------------------------------------------------
                COMMON  INTVEC                  ; Interrupt Vectors
    ;------------------------------------------------------------------------------
                ORG     USCIAB0TX_VECTOR        ; USCI_A0 I2C Data Int Vector
                DW      USCIA0TX_ISR
                ORG     RESET_VECTOR            ; MSP430 RESET Vector
                DW      RESET                   ;

    However, it seems to not working
    the ORGs should place the following constant to the location of the USCIAB0TX_VECTOR and the RESET_VECTOR in the INTVEC segment.
    But somehow it doesn't seem to place the two values where tehy belong.
    I don't know why. You should consult the compiler/assembler manual or look into working demo code.

    I just checked some other code examples and the interrupt vectors are define dthere exactly as you did.
    You should ocnfigure the linker to put out a map file and check where your INTVEC segment goes to. As well as where your code is placed to.

     

    One more thing:

    sunil sharma said:
    ;-------------------------------------------------------------------------------
                RSEG    CSTACK                  ; Define stack segment
    ;-------------------------------------------------------------------------------
                RSEG    CODE                    ; Assemble to Flash memory
    ;-------------------------------------------------------------------------------
                RSEG    INFO                  ; Assemble to INFORMATION MEMORY
    ;-----------------------------------------------------------------------------
    RESET       mov.w    #SFE(CSTACK),SP    ;#02100h,SP;   ; Initialize stackpointer      
    Here you define three segments for use with the following code. However, 'last one wins'. So your reset function will be written into INFO memory rather than main flash memory.
    RSEG has to be used immediately before the code that shall go into this segment. So only one is required, and it normally should be 'CODE'.

  • Hi Michael....checked the things you told 

    <<<You should ocnfigure the linker to put out a map file and check where your INTVEC segment goes to. As well as where your code is placed to.

    SEGMENT              SPACE    START ADDRESS  

    =======              =====    =============   =

    CSTACK                                 20B0 - 20FF            

    <CODE> 1                               2100 - 21AD          

    INTVEC                                 FFA0 - FFDF          

     

    The .mapfile also showed the following information

    #                            -Z(DATA)CSTACK+_STACK_SIZE#                       #

    #                            -Z(CODE)INFO=2100-FFBF                            #

    #                            -Z(CODE)CSTART,ISR_CODE=2100-FFBF                 #

    #                            -Z(CONST)DATA16_C,DATA16_ID,DIFUNCT=2100-FFBF     #

    #                            -P(CODE)CODE=2100-FFBF,                           #

    #                            -Z(CONST)DATA20_C,DATA20_ID=2100-FFBF,10000-1FFFF #

    #                            -Z(CODE)INTVEC=FFA0-1FFFF                         #

    #                            -Z(CODE)RESET=FFFE-FFFF) -f

     

    From what you have said I understand that-

    The INTVEC segment is not starting from FFFF downwards as it is supposed to. So I checked the memory locations FFDF and found 2100 and FFD0 had address of the UCA0-TX ISR.

    But I wanted to know how to overcome this and is the program going into void because it can not find the ISR.

    Will I be able to use interrupts without correcting this problem.

  • Hi Michael

    tried the tutorials, they were working fine ....

    so just copied there initial declaration onto my pgm and ran... PC came to 2100

    ---------------------------------------------------------------------------------------------------------

            NAME    main                    ; module name

            PUBLIC  main                    ; make the main label vissible      outside this module            

            ORG     0FFFEh

            DC16    init                    ; set reset vector to 'init' label

            RSEG    CSTACK                  ; pre-declaration of segment

            RSEG    CODE                    ; place program in 'CODE' segment

    init:   MOV     #SFE(CSTACK), SP        ; set up stack-Initialize stackpointer

    main nop

    --------------------------------------------------------------------------------------------------------------

    But still having the problem with the ISR even though its correct address is in the Int Vector table. The pgm goes into void on enabling GIE not the TX int

    --Secondly, Iam not able to get clock on oscilloscope on P7.3  .    Also saw SMCLK on P1.4 (after configuring P1SEL & P1DIR)  and  but it was not available.

     

    Thanks a lot for your help....

  • Hi Michael

    After changing the initial declarations Iam getting this error-  

    The stack pointer for stack 'Stack' (currently Memory:0x65A84) is outside the stack range (Memory:0x20B0 to Memory:0x2100) 

    Maybe as a result of this when Iam sigle-stepping
    my UCA0_TXBUF-SPI is not outputting the correct values from a stored location(0x01,2,3...) which it was doing earlier correctly.
    Instead it is showing 0x82,0x02,0xB2,0xA6 etc.
     
    Also I can now see the SMCLK on both the pins(7.3 and 1.4) only when I press GO. On single stepping there is no clock seen on the scope. Is the ok?
     
    Iam working on MSP communication with DSPC55 on mcBSP.
    Also when I run the pgm it goes in a loop and I have to break the operation. Any idea why this happens (interrupts?).
    The DSP side is not configured and running yet.
  • sunil sharma said:
    The INTVEC segment is not starting from FFFF downwards as it is supposed to.

    Actually, all segments have a start address and a size. They are not 'top-down'. However, INTVEC should end at 0xffff. I checked the datasheet, and it tells that the interrupt section begines at 0xFFC0. In your case, it is linked to 0xFFA0, and it therefore ends 32 bytes too early.

    I don't know where this (wrong) FFA0 start address for INTVEC comes from. Maybe a bug in the linker command script, or the wrong linker command script is loaded (wrong project config)?

    The addresses your source code did put into INTVEC are correct, relative to the (unfortunately wrong) start address of INTVEC.

    I'm sorry, but since I don't use IAR, I cannot help you further.

    You shoudl post the version of your compiler suite and maybe a screenshot of your project settings. perhaps someone else can give you some further advice.

    By just checking the device datasheets and the code and map file you posted, I doN't see a problem with your code itself. Only with what is created from this code.

    sunil sharma said:
    But I wanted to know how to overcome this and is the program going into void because it can not find the ISR.

    Yes. because the address of your ISR and your programdoesn't end up where it should, the processor does not know where to find them. It's like a PC when you remove the BIOS chip - it cannot boot even if the OS is properly installed on the HD.

    sunil sharma said:
    Will I be able to use interrupts without correcting this problem.

    YOu won't be able to run a program at all without correcting this, as hte program applies to the start address of your main code as well as to the ISRs.

    There could be a quick and dirty hack that might work:

    add a '+32' at the end of the two ORG instructions. This should move th eentries 32 bytes further up in the address space, so they will land where the should be despite of the wrong start address of INTVEC. But that's a dirty hack (the cause of the problem still exists) and I'm not sure whether it will work at all. But it's surely worth a try while you wait for a 'real' solution.

     

  • sunil sharma said:
    ORG     0FFFEh

    This places the following word (which is teh address of your main code) explicitely at address 0xfffe, relative to the current segment. Hwoever, there is no current segment, so it ends up to be the absolute position.

    Many examples are done this way, which is, well, sufficient for a few code lines but absolutely inadequate or any project, even small size.
    Or it is a quick, dirty, and - worse - undocumented hack around a defective linker command script.

    Once again: your code was fine, it was the linker that was not acting as it should.

    sunil sharma said:
    Secondly, Iam not able to get clock on oscilloscope on P7.3

    There is a clock only if something was written to TXBUF. Adn onlywhile the content of TXBUF is being sent. It is nto a continuous clock. Only 8 pulses per byte and only while the byte is transmitted. Sicn eyour ISR is not called, nothing is written to TXBUF and nothing sent and therefore no clock signal. Also, during single-stepping, teh clocks are frozen as well as MCLK is. You'll oly see an occasional blip on the scope in the moment you do a single step.

    Perhaps you should repost your code in its current form again. You made several changes, so we cannot be sure that we talk about the same anymore.

    And, please, remove the double-linefeeds between the source code (shift-return instead of a normal return). It is very lengthy otherwise and difficult to read,

     

  •  Hi Michael,

    Created a new workspace and a new assembler only project with default settings. Then on debugging the PC went correctly to RESET (2100).
    Checked the INTVEC segment. It was at the right place.  -Z(CODE)INTVEC=FFC0-FFFF .

    Now I am trying to get the SPI going without any interrupt. When I run the code (GO) I get the error illegal opcode at 0x00. On single stepping the after reaching RETI this error is generated. 
    I also wanted to ask how to use interrupt for transmission . I tried a bit but could not succeed. Have removed that part from the code.

    Also, now I can't see the clock on  P7.3 or P1.4 on pressing GO...maybe because of this error

    The code is here

    #include  <msp430xG46x.h>       

                RSEG    CSTACK                  ; Define stack segment
                RSEG    CODE                    ; Assemble to Flash memory
    ;-----------------------------------------------------------------------------
    RESET       mov.w    #SFE(CSTACK),SP    ; Initialize stackpointer
    main           nop
    StopWDT     mov.w   #WDTPW+WDTHOLD+WDTNMI+WDTTMSEL+WDTSSEL,&WDTCTL  ; Stop WDT
    setupSVS    mov.b   #018h,&SVSCTL            ;Vth = 1.9V
    setupRTC    mov.b   #30h,&RTCCTL
    bis.b   #RTCBCD,&RTCCTL
    ;...............................................................................
                mov.w   #TX_DATA,R15          ;ADDRESS OF TX_DATA IN R15
                mov.w   #08,R10 

    TX_DATA     DB 01H
                      DB 02H
                DB 03H
                DB 04H
        DB 05H
                DB 06H
                DB 07H
                DB 08H
    ;----------------------------------------------------------------
    ;CONFIGURE PORT8 FOR SELECTING THE SLAVE VIA 1:8 MUX-DEMUX
    ;----------------------------------------------------------------
    SetupP8     mov.b   #070h,&P8DIR            ;CONFIGURE THE PORT FOR S0,S1,S2
                mov.b   #00h,&P8SEL  
                mov.b   #000h,&P8OUT            ; SELECT DSP1 of 4 DSPs  
               bic.b   #BIT0,&P7OUT;   MAKE SS LOW BY SETTING P7.0 LOW
    ;----------------------------------------------------------------;
    SETUP MSP430 FOR SPI-McBSP INTERFACE;
    -----------------------------------------------------------------    
    SetupSPI    ;bis.b   #UCSWRST,&UCA0CTL1 
               bis.b   #UCMST+UCSYNC+UCCKPL+UCMSB,&UCA0CTL0;3-pin, 8-bit SPI master
                bis.b   #UCSSEL_2,&UCA0CTL1     ; SMCLK
                mov.b   #64h,&UCA0BR0           ; /2
                clr.b   &UCA0BR1              ;
               clr.b   &UCA0MCTL               ; No modulation

    ;Configure ports

    SetupP7    bis.b   #0Eh,&P7SEL             ; P7.3,2,1 option select as USCI_A0
                        bis.b   #01h,&P7DIR             ;Dirxn of STE as output as IO P7.0

                  bic.b   #UCSWRST,&UCA0CTL1      ; **Initialize USCI state machine**  ;...............................................................................

                bic.b   #BIT0,&P7OUT             ; Now with SPI signals initialized,
                bis.b   #BIT0,&P7OUT             ; reset slave; MAKE SS LOW BY SETTING P7.0 LOW - 

    ;Observe SMCLK on P1.4
                BIS.B   #BIT4,&P1SEL ; Select SMCLK/n signal as output for port P1.4
                BIS.B   #BIT4,&P1DIR ; Select port P1.4 to ACLK/n

                mov.w   #50,R14                 ; Wait for slave to initialize
    waitForSlv     dec.w   R14                     ;
                jnz     waitForSlv                     

    Mainloop   mov.b @R15+,&UCA0TXBUF
               mov.w   #2,R11                  ; Add time between transmissions to
    cycleDelay dec.w   R11                     ; make sure slave can keep up
               jnz     cycleDelay      

               dec R10                         ;Tx 8 characters
             jnz Mainloop 
             reti         
    ;------------------------------------------------------------------------------
                COMMON  INTVEC                  ; Interrupt Vectors
    ;------------------------------------------------------------------------------
                ORG     RESET_VECTOR            ; MSP430 RESET Vector
                DW      RESET                   ;
                END

    And about starting another thread... you were right ..I shouldn't have because of the references....But I thought that the initial error was over and this was some other issue...

  • the error for opcode was because I had default settings of debugger as simulator in the newly created project...

    saw a similar thread....

    can see the clock now...(SMCLK 297 KHz)

    Now I am trying to get the SPI going without any interrupt.  

    I also wanted to ask how to use interrupt for transmission/reception .

    I tried a bit but could not get it right.  Have removed that part from the code.

     

  • sunil sharma said:
                mov.w   #TX_DATA,R15          ;ADDRESS OF TX_DATA IN R15
                mov.w   #08,R10 

    TX_DATA     DB 01H
                      DB 02H
                DB 03H

    What are you doing here? After the mov.w instruction you have data. What is the processor supposed to do when it has executed mov.w? It will fetch the data as instructions and tries to execute them, resulting in whatever. If you're lucky, it will pass this part without doing any real harm, but it could do anything, depending on what this data means if takes as instruction.

    sunil sharma said:
             reti         ;

    Where do you return to? You never called this code as a function so there is nobody you could return to.
    Also, RETI means 'return from interrupt' (hence the 'i'). It means that the (by the interrupt logic) saved status register is fetched from stack, then the return address. But you are not in an interrupt, so the status register will be filled with the return address (maybe causing an LPM entry or whatever) and the last word on stack is taken as return address (jumping to whatever).
    But since you didn't call this function, there is no return address on stack too, so 'something' is fetched from stack as status register and return address. Since you never put something on stack at all, it is likely the first two words above the stack pointer: the first two words of your program.

    The proper exit of a function that has been called with the CALL instruction is RET.

  • Hi Michael


    1) I have removed the TX_DATA and RETI as you suggested 

    2) I am able to receive data on the DSP via SPI-McBSP. Howevr, when Iam transmitting from DSP to MSP -
    On transmitting 0/1h I am receiving 0 on MSP.
    On transmitting 2/3h I am receiving 1 
    On transmitting 4/5h I am receiving 2 

    Any idea why this is happening. On seeing the MISO line on scope , the graph for a 2/3h transmission from DSP look similar.
    Will post the graphs soon. But any idea what I should look for.

    3) On the IAR - When I press Go and run the code the transmission begins but on breaking the Pgm Counter reaches some place outside the code and does not return to RESET. However on running again it resumes normally. Is this alright.

    And thanks a ton for your constant guidance.
    You have been a real help..... 

  • sunil sharma said:
    On transmitting 0/1h I am receiving 0 on MSP.
    On transmitting 2/3h I am receiving 1 
    On transmitting 4/5h I am receiving 2 

    THis look slike MSP and DSP are using a different clock phase or polarity. So you're one bit off. (5>>1 = 2, 4>>1 = 2, 3>>1=1 etc.)

    The USCI has settings for phase and polarity, you can play with them and see whether it solves the problem.

  • Will check the CLK phase and polarity.

    Presently the code is set to work without the Tx/Rx interrupt. I want to make it interrupt driven.

    I think that as the transmission from the MSP 430 may be without interrupt, but it is better to have an ISR for reception. The procedure for reception will start with the DSP generating an interrupt and then the MSP will have to initiate the RX_ ISR for reception.

    I also I wanted to know that -  When I press Go and run the code on MSP 430 the transmission begins but on breaking the Pgm Counter reaches some place outside the code and does not return to RESET. However on running again it resumes normally. Is this alright.

    And even on stopping by breaking the execution of the code, the MSP transmission the DSP continues to receive data. Is this because the SS sgl might be active for the slave.
    But there is no txn from the MSP 430. Even if something is there in the TXBUF the same value should be Txd over MOSI. Instead I continue to receive whatever I was Txg earlier that is 00h to 64h.

    Have placed the code as an attachment

    I may be asking all the questions for my convenience but I am working towards the same......

    Regards

    Sunil 

     

  • Forgot to attach the code

    #include  msp430xG46x.h
                
                RSEG    CSTACK                  ; Define stack segment
                RSEG    CODE                    ; Assemble to Flash memory
    ;-----------------------------------------------------------------------------
    
    
    RESET       mov.w    #SFE(CSTACK),SP    ;#02100h,SP; Initialize stackpointer
               ; bis.b   #GIE,SR             ;enabling general interrupts
    main        nop
    StopWDT     mov.w   #WDTPW+WDTHOLD+WDTNMI+WDTTMSEL+WDTSSEL,&WDTCTL  ; Stop WDT
    setupSVS    mov.b   #018h,&SVSCTL            ;Vth = 1.9V
    setupRTC    mov.b   #30h,&RTCCTL
                bis.b   #RTCBCD,&RTCCTL
    ;----------------------------------------------------------------
    ;CONFIGURE PORT8 FOR SELECTING THE SLAVE VIA 18 MUX-DEMUX
    ;----------------------------------------------------------------
    SetupP8     mov.b   #00h,&P8SEL             ;CONFIGURE AS GPIO
                mov.b   #70h,&P8DIR            ;CONFIGURE THE PORT FOR S0,S1,S2 AS OP
                mov.b   #00h,&P8OUT            ; SELECT DSP1 of 4 DSPs          
    ;----------------------------------------------------------------            
    ;Configure ports for SPI and SS(as GPIO-active low)
    ;----------------------------------------------------------------
    SetupP7    bis.b   #0Eh,&P7SEL             ; P7.3,2,1 option select as USCI_A0
                                                ; P7.0 as IO pin for controlling STE
               bis.b   #01h,&P7DIR             ;Dirxn of STE as output as IO P7.0
               ;bic.b   #BIT0,&P7OUT            ;MAKE SS LOW BY SETTING P7.0 LOW -            
    ;----------------------------------------------------------------
    ;SETUP MSP430 FOR SPI-McBSP INTERFACE
    ;----------------------------------------------------------------            
    SetupSPI    bis.b   #UCSWRST,&UCA0CTL1           
    ;Initialize all USCI registers with UCSWRST=1          
               bis.b   #UCMST+UCSYNC+UCCKPL+UCMSB,&UCA0CTL0;3-pin, 8-bit SPI master
               bis.b   #UCSSEL_2,&UCA0CTL1     ; SMCLK
               mov.b   #255,&UCA0BR0           ; 255
               clr.b   &UCA0BR1                ;
               clr.b   &UCA0MCTL               ; No modulation
    ;Clear UCSWRST
               bic.b   #UCSWRST,&UCA0CTL1      ; Initialize USCI state machine                      
    ;Enable interrupts (optional)            
              ;bis.b   #UCA0TXIE,&IE2          ; Enable USCI_A0 TX interrupt
              ;bis.b   #UCA0RXIE,&IE2          ; Enable USCI_A0 RX interrupt           
              ;bis.b   #LPM0+GIE,SR            ; CPU off, enable interrupts
    ;..............................................................................
    ;TX OF DATA
    
               mov.b   #64h,R10                  ;down counter
               mov.b  #00,R4                    ; data to be txd
               bic.b   #BIT0,&P7OUT            ;MAKE SS LOW BY SETTING P7.0 LOW -  
    Mainloop   mov.b  R4,&UCA0TXBUF
               
               
               
    TX1	   bit.b #UCA0TXIFG,&IFG2	    ;TX Buffer ready
    	   jz TX1
               
    RX1	   bit.b #UCA0RXIFG,&IFG2	    ;RX Buffer ready
    	   jz RX1
               mov.b  &UCA0RXBUF,R5
    
               inc.b  R4           
    ;RESET SLAVE AFTER EVERY TRANSMISSION
                bis.b   #BIT0,&P7OUT  ; Now with SPI signals initialized,
                bic.b   #BIT0,&P7OUT  ; reset slave; MAKE SS LOW BY SETTING P7.0 LOW - 
                                                 ;will require to out 0 from 7.1
                                                 ;or and with FE to make 7.0 low            
                mov.w   #50,R14                 ; Wait for slave to initialize                                      
    waitForSlv  dec.w   R14                     ;
                jnz     waitForSlv                     
                            
               ;mov.w   #2,R11                  ; Add time between transmissions to
    ;cycleDelay dec.w   R11                     ; make sure slave can keep up
               ;jnz     cycleDelay                
                
               dec R10                         ;Tx 8 characters
               jnz Mainloop                     
    
                                                                                                                                          
    ;------------------------------------------------------------------------------
                COMMON  INTVEC                  ; Interrupt Vectors
    ;------------------------------------------------------------------------------
    ;           ORG     USCIAB0TX_VECTOR        ; USCI_A0 I2C Data Int Vector
    ;           DW      USCIA0TX_ISR
                ORG     RESET_VECTOR            ; MSP430 RESET Vector
                DW      RESET                   ;
                
                END

  • Hi Michael
    Changed the polarity of the clk and getting the data correctly on both sides.

    Can you plz tell about some of my aueries in the previous post 

    Thanks

  • sunil sharma said:
    Changed the polarity of the clk and getting the data correctly on both sides.

    Great.

    sunil sharma said:
    I think that as the transmission from the MSP 430 may be without interrupt, but it is better to have an ISR for reception. The procedure for reception will start with the DSP generating an interrupt

    Reception in the background is a good thing. However, if you want high speed transfers, a busy-waiting transfer is fastest. On the 5438, I do SPI transfers to/from SD card with full 16MHz SPi clock (2MB/s peak transfer rate). Well, the wait times for fetching a block or writing it drop the overall performance, but with interrupts, I wouldn't come near this speed.
    For the (slower) UARTs, I use ISR s with a ring buffer for sending and receiving. When I have to send something, i can fire&forget, and I can check whether something was received when my code wants to (either getting something from the buffor or gettign a timeout). That's really convenient.

    For I2C, I too prefer busy-waiting but this depends on the type of information you want to transfer. (on short transfers, the setup overhead is much larger than what you gain for a background handling)

    sunil sharma said:
    and then the MSP will have to initiate the RX_ ISR for reception.

    You cannot call an ISR from main directly. This will crash the system. An ISR expects the status register on the stack after the return address (which you cannot simulate easily in software).

    sunil sharma said:
    On the IAR - When I press Go and run the code the transmission begins but on breaking the Pgm Counter reaches some place outside the code and does not return to RESET. However on running again it resumes normally. Is this alright.

    Hmm, strange. Normally, it should break where you currently are and not in the void.
    Why should it return to RESET? When you break the execution, you should stop somewhere in the main loop.

    sunil sharma said:
    And even on stopping by breaking the execution of the code, the MSP transmission the DSP continues to receive data. Is this because the SS sgl might be active for the slave.


    Strange again. When the MSP is slave, then stopping the CPU does nto stop the USCI. The clock is provided externally, so teh external master continues to clock the bus and sends data, and when the USCIs TX buffer is empty, it will continue sending, well, I don't know what i sends then.

    If the MSP is master, then ther eare two possibilities: eithe rthe clock that drives the USCI is stopped by the debugger too, then the SPI immediately stops sending. On some slaves, the transfer can be continued after any delay, on some there will be a timeout.

    If the clock is not stopped by the debugger (not possible on some devices, or not selected in the config), then the SPI sends until TXBUF is empty and then stops, since the CPU is not stuffing more into TXBUF.

    When you see it continuing, it looks like there is a problem with the debug interface (and the wrong display of teh code address fits to this assumption). If so, I cannot help you there. I don't use IAR or CCS. I don't even use a debugger at all for my MSP projects.

  • Jens-Michael Gross said:

    Reception in the background is a good thing.
    My aim is to interface the master with 4 DSP slaves. The connection is as shown

    Now I have been able to undertake simple SPI communication between MSP430 and DSp1.

    However, it is actually supposed to work like this

    a) DSP1/2/3/4 interrupts MSP430 using HINTDSP via a priority encoder.      The priority encoder output (HINT1,2,3) is connected with pins P1.2/4/6.

    b) The MSP430 decodes/finds which DSP has generated interrupt and then initiates communication with that DSP.

    c) This is why I was thinking of using interrupts and ISRs to select the appropriate DSP for communication.

    d) There is another signal from the encoder to the DSP HINT# connected at P2.6, which changes state on any DSP sending a request for communication.

    I am planning to use this P2.6 as an interrupt pin and thereafter having an ISr to check the P1IN register for the highest priority DSP which has generated the request.

    Is this okay to go ahead with, or shall I do it differently.

    and then the MSP will have to initiate the RX_ ISR for reception.

    You cannot call an ISR from main directly. This will crash the system. An ISR expects the status register on the stack after the return address (which you cannot simulate easily in software).

    If I cannot use an ISR, then what is the way out???

    I dont require high speed data transfers. The DSPs will mostly be sending health data or some processed data or results.
    Will it be alright to establish communication with each DSP in a sequential manner and receive any data if it is there. However, i feel this will lead to keeping MSP and DSP unnnecessarily busy if the DSPs are in sleep mode and dont have anything to transmit. Hence not an ideal solution.

    Thanks

     

    [/quote]

     

  • Hi Michael,

    I am trying to interface a FLASH to MSP430 using SPI. Can you help me with it. Here is the link for the thread

    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/137111/496266.aspx#496266

    Regards..

    Sunil

**Attention** This is a public forum