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 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?
Brandon
sunil sharmawhenever I debug my program, the Program Counter goes to 0xFFFE.
_____________________________________Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.
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 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 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.
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 -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-Is it necessary to use FLL/DCO as in example code.
sunil sharma-Is it necessary to reset the slave after every transmission or a delay shall suffice between transmissions.
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-Also looking at the code, can you please tell why PC is going to 0xFFFE initially instead of 0x2100.
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 sharmaThe value I watched at the 0xFFFE in memory while debugging is FFFF.
This code should normally define the vectors:
sunil sharma;------------------------------------------------------------------------------ COMMON INTVEC ; Interrupt Vectors ;------------------------------------------------------------------------------ ORG USCIAB0TX_VECTOR ; USCI_A0 I2C Data Int Vector DW USCIA0TX_ISR ORG RESET_VECTOR ; MSP430 RESET Vector DW RESET ;
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;------------------------------------------------------------------------------- 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
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
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....
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)
sunil sharmaThe INTVEC segment is not starting from FFFF downwards as it is supposed to.
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 sharmaBut I wanted to know how to overcome this and is the program going into void because it can not find the ISR.
sunil sharmaWill I be able to use interrupts without correcting this problem.
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 ORG 0FFFEh
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 sharmaSecondly, Iam not able to get clock on oscilloscope on P7.3
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,