I've been fighting a very strange problem with the USI module. Occasionally, USICNT spontaneously takes on strange values. I've attached a short program that demonstrates the problem. It shows up on different chips (both 14-DIP and TSSOP-14) in various circuit setups, including a simple ez430-F2013. It is extremely timing-sensitive, to the point where slight changes to bus capacitance make the problem show up or disappear.
Am I doing something wrong that's causing this? If not, is there anything I can do to avoid it? It's wreaking havoc with my system.
Thanks!
John-Paul Gignac
;***********************************************************************
;* This program demonstrates a glitch in the MSP430F2013's USI module. *
;* I've tested it successfully with the EZ430-F2013, as well as other *
;* setups. If the glitch doesn't show up within a few moments, try *
;* modifying the impedance of SCL very slightly by placing your hand *
;* near, or attaching a long (eg, 24 inches) conductor to pin 8. *
;***********************************************************************
#include "msp430x20x2.h"
RSEG CSTACK ; Define stack segment
RSEG CODE ; Assemble to Flash memory
EVEN
RESET mov #0x5A80, &0x0120 ; Stop watchdog timer
mov.w #SFE(CSTACK),SP ; Initialize the stack pointer
; Set the clock speed to around 1MHz
mov #0x86BA, &0x0056
; Setup pin assignments
mov.b #0xFF, &0x0021 ; P1OUT = 0xFF
mov.b #0xFF, &0x0022 ; P1DIR = 0xFF
mov.b #0x00, &0x0026 ; P1SEL = 0x00
mov.b #0xC0, &0x0027 ; P1REN = 0xC0 ; P1.6 & P1.7 Pullups
; Setup the USI in master mode
mov.b #0xCB, &0x0078 ; USICTL0 ; Initiate software reset
mov.b #0x50, &0x0079 ; USICTL1
mov.b #0x6A, &0x007A ; USICKCTL ; SMCLK / 8
mov.b #0x00, &0x007B ; USICNT = USIIFGCC
mov.b #0xCA, &0x0078 ; Finish the software reset
mov.b #0x50, &0x0079 ; Clear the interrupt flags
eint
main_loop
; Begin with a short delay
mov #500, r12
delay
dec r12
jne delay
clr r7
mov.b #0x08, &0x007B ; Start transmitting 8 bits
;****************************************************************
;* We watch for the glitch while the byte is being transmitted. *
;* The symptom is that USICNT spontaneously takes on a value *
;* higher than what was assigned to it. A typical observed *
;* value is around 0x1A. *
;****************************************************************
watch_for_glitch
cmp.b #0x09, &0x007B
jhs glitch
tst r7
jeq watch_for_glitch
jmp main_loop
glitch
;************************************************************************
;* Place a breakpoint here or trigger your oscilloscope on P1.0 (pin 2) *
;************************************************************************
dint
bic.b #1, &0x0021
bis.b #1, &0x0021
mov.b #0x00, &0x007B
bic.b #3, &0x0079
eint
jmp main_loop
;*****************************
;* Interrupt Service Routine *
;*****************************
USI_ISR mov #1, r7
bic.b #1, &0x0079
reti
COMMON INTVEC
ORG RESET_VECTOR ; MSP430 RESET Vector
DW RESET ;
ORG USI_VECTOR ; USICNT
DW USI_ISR ;
END