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; } }