Tool/software:
Hello:
Thank you in advance for any help that you can provide. I am running an app on the MSP-EXP430G2 Launchpad Development Kit with an older circuitco educational boosterpack. The app determines the speed of a spindle using a hall effect sensor and displays it on the boosterpack lcd when I am debugging the app but when I quit the debugger, the last bit of information displayed on the lcd before quitting remains and there is no update of spindle speed. The app also does not work when I remove jumpers for the emulation board and power the unit from an external power supply via J6. After powering up, I have to hit reset button and then only see the beginning splash screen no display of spindle speed.
I have looked at various forum examples of code running with debugger and not when the debugger is shut down but I cannot see what is relevant to my situation in those examples.
Do you have any suggestions how I might be able to troubleshoot this? Thanks again.
Set up:
Code composer studio Version: 11.1.0.00011, pc running windows 10.
Watch crystal installed on launchpad board and white LED on edu boosterpack removed (I am using that pin 13 as an input from the hall effect sensor circuit).
Hall effect sensor circuit.

and my code.
#include <msp430.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <intrinsics.h>
#define EBP_CS BIT0 //chip select
#define EBP_CLK BIT5 //clock
#define EBP_MOSI BIT7 //data line
#define EBP_RS BIT3 //command vs data
#define SENSOR_PIN BIT5 //attach key to P2_5 TA1.2
#define AFTER_BUSY_DELAY 40 //used to wait additional time after UCBUSY clears
void InitBPLCD(void);
void InitSPI(void);
void InitPorts(void);
void InitHallSensor(void);
void itoa(long unsigned int value, char *result, unsigned int base);
unsigned int WriteCommand(unsigned int cmd);
void WriteData(void);
void ClearHome(void);
void SetRowLine(unsigned int row, unsigned int line);
char charsToLCD[32] = {'\0'};
uint32_t timerDiff = 0;
uint8_t computeSpeed = 0;
uint8_t speedCount = 0;
volatile unsigned int cntOvrFloTAR = 0;
volatile unsigned int sendData = 0;
volatile uint16_t currTimerCounts = 4;
volatile uint16_t prevTimerCounts = 0;
/**
* main.c
*/
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
//set up Basic Clock Module
BCSCTL1 |= DIVA_3; //this write clears all other bits; divide ACLK/8
BCSCTL3 |= XCAP_3; //sets internal capacitance for watch crystal
InitPorts();
InitSPI();
InitHallSensor();
InitBPLCD();
__delay_cycles(1000);
strcpy(charsToLCD, "0123456789012345testing testing!");
WriteData();
__delay_cycles(1000);
//Set up Timer1A
// capture on rising edge, CCI2B input, synchronous cap, capture mode, ints enabled
TA1CCTL2 = CM_1 | CCIS_1 | SCS | CAP | CCIE;
// Continuous, divide clock by 1, ACLK, clear, enable
TA1CTL = MC_2 | ID_0 | TASSEL_1 | TACLR | TAIE;
__enable_interrupt();
for(;;){
// do nothing
if (computeSpeed > 0){
computeSpeed = 0;
timerDiff = currTimerCounts - prevTimerCounts;
//clear buffer
charsToLCD[0] = '\0';
itoa(timerDiff, charsToLCD, 10);
WriteData();
}
/*
if (sendData == 2)
{
sendData = 0;
charsToLCD[0] = '\0';
strcpy(charsToLCD, "0123456789012345running testing!");
WriteData();
}
*/
}
return 0;
}
#pragma vector = TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR (void){
switch (__even_in_range(TA1IV, 10)){
case 0:
break;
case TA1IV_TACCR2:
TA1CCTL2 &= ~CCIE; // disable further CCIE interrupts
prevTimerCounts = currTimerCounts;
currTimerCounts = TA1CCR2;
++speedCount;
if (speedCount > 3){
computeSpeed = 1;
speedCount = 0;
}
cntOvrFloTAR = 0; //reset TAR rollover counter
TA1CCTL2 &= ~CCIFG; // clear the CCRO flag
TA1CCTL2 |= CCIE; //enable interrupts
break;
case TA1IV_TAIFG:
++cntOvrFloTAR;
/*if (cntOvrFloTAR > 2){ // been idle
//set flag to go to sleep
cntOvrFloTAR = 0;
sendData = 2;
}else{
sendData = 1;
}*/
break;
default:
for (;;){
//Should not be possible
}
}
}
void InitBPLCD(void){ //copying bp_LCD.cpp from Energia sketch
WriteCommand(0x30); //function set
__delay_cycles(27);
WriteCommand(0x30); //function set
__delay_cycles(27);
WriteCommand(0x30); //function set
__delay_cycles(27);
WriteCommand(0x14); //cursor/display shift
__delay_cycles(27);
WriteCommand(0x0c); //display on/off
__delay_cycles(27);
WriteCommand(0x06); //entry mode set
__delay_cycles(27);
WriteCommand(0x39); //function set (2 lines, instruction table 1)
__delay_cycles(27);
ClearHome(); //clear
WriteCommand(0x57); //power/ICON control/contrast set upper bits
__delay_cycles(27);
WriteCommand(0x6b); //follower control
__delay_cycles(27);
WriteCommand(0x72); //contrast set lower bits
__delay_cycles(1000);
}
unsigned int WriteCommand(unsigned int cmd){
if (UC0IFG & UCB0TXIFG){ //ready for new data?
P2OUT &= ~(EBP_RS + EBP_CS); // need to clear _SS and RS LOW for command
__delay_cycles(10);
UCB0TXBUF = cmd; //begin transaction
while(UCB0STAT & UCBUSY); //wait for transfer to finish
__delay_cycles(AFTER_BUSY_DELAY);
P2OUT |= EBP_RS + EBP_CS;
}
__delay_cycles(5);
return 1;
}
void ClearHome(void){
unsigned int wait = WriteCommand(0x01);
if (wait == 1){
WriteCommand(0x02);
}
}
void WriteData(void){
ClearHome();
SetRowLine(0,0);
char *ptr_lcdUp = charsToLCD;
char *ptr_lcdLow = charsToLCD + 16;
unsigned int i;
for(i = 0; i < 16 && *ptr_lcdUp != '\0'; ++i, ++ptr_lcdUp){
if (UC0IFG & UCB0TXIFG){ //ready for new data?
P2OUT &= ~EBP_CS;
__delay_cycles(10);
UCB0TXBUF = *ptr_lcdUp; //load shift register for transfer
while(UCB0STAT & UCBUSY); //wait for transfer to finish
__delay_cycles(AFTER_BUSY_DELAY);
P2OUT |= EBP_CS; // need to set _SS HIGH
}
}
SetRowLine(0,1);
for(i = 0; i < 16 && *ptr_lcdLow != '\0'; ++i, ++ptr_lcdLow){
if (UC0IFG & UCB0TXIFG){ //ready for new data?
P2OUT &= ~EBP_CS;
__delay_cycles(10);
UCB0TXBUF = *ptr_lcdLow; //load shift register for transfer
while(UCB0STAT & UCBUSY); //wait for transfer to finish
__delay_cycles(AFTER_BUSY_DELAY);
P2OUT |= EBP_CS; // need to set _SS HIGH
}
}
}
void SetRowLine(unsigned int row, unsigned int line){
//NewHaven LCD with 2 lines 16 rows, expect line (0,1) row (0,15)
if ((row < 16) && (line < 2))
WriteCommand(0x80 | (line * 0x40) | row);
}
void InitSPI(void){
P2OUT |= (EBP_CS | EBP_RS); //start off high (
P1SEL |= (EBP_CLK | EBP_MOSI); //select primary peripheral USCI_B
P1SEL2 = (EBP_CLK | EBP_MOSI);
//SPI mode 3 needs CPOL=CKPL=1, CPHA=1 -> CKPH=0; msb first, master,
//8 bit (default), 3-wire (default, mode 0), synchronous
UCB0CTL0 = UCCKPH | UCMSB | UCMST | UCMODE_0 | UCSYNC;
UCB0CTL1 = UCSSEL1 | UCSWRST; //clock from SMCLK; hold in reset
UCB0BR1 = 0; //upper byte of divider word
UCB0BR0 = 60; //Clock = SMCLK/60 = 100KHz
UCB0STAT = UCLISTEN; //Internal loopback; try this since no MISO pin
UCB0CTL1 &= ~UCSWRST; //release from reset
}
void InitPorts(void){
P1OUT = 0;
P1DIR = 0xFF;
P2OUT = 0;
P2DIR = 0xFF;
}
void InitHallSensor(void){
P2DIR &= ~SENSOR_PIN; //Set pin as input
P2SEL |= SENSOR_PIN; //Set pin for Timer1_A CCI1A capture
}
void itoa(long unsigned int value, char* result, unsigned int base){
// check that the base is legit
if (base < 2 || base > 36) { *result = '\0';}
char *ptr = result, *ptr1 = result, tmp_char;
unsigned int tmp_value;
do{
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while (value);
//Apply negative sign
if(tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr){
tmp_char = *ptr;
*ptr-- = *ptr1;
*ptr1++ = tmp_char;
}
}