Reply by Dan Bloomquist February 10, 20112011-02-10
old_cow_yellow wrote:
> Dan,
>
> You are right. But for WDTCTL and other registers with "password", there is another wrinkle. Examples:
> ----
> WDTCTL = WDT_MRST_32 + ~WDTHOLD;
> is the same as WDTCTL = 0x5983; and will cause a WDT password violation reset.
> -----
> WDTCTL = ~WDTHOLD;
> is the same as WDTCTL = 0xFF7F; and will also cause the same reset.
> -----
> WDTCTL&= ~(anything);
> WDTCTL |= (anything);
> will cause reset too, no matter what (anything) is.
> -----
> WDTCTL ^= 0x3300 | (8_bit_mask);
> will flip those (8_bit_mask). Password will be correct.
> =====>
> --OCY
>
>

Yes OCY,
And I had just read through the watchdog a few weeks ago while working
out the clock sources. Gota use that password. I've only either disabled
the watchdog or set it off for tick interrupts when I have a watch
crystal attached. So I've only set it up at initialization. Ryan, you
may want to consider that, just use the interrupt to check state flags
and work counters. As your project is a refer control and you don't LPM,
just work a counter and leave the watchdog alone. Set it for one second
ticks, (use that crystal), and do a RTC thing. My last project shows
time in the LCD display when powered up, I'm counting seconds, minutes,
hours, days... With power down only the WDT interrupt is hit to keep the
RTC updated. So, if you extend your code for LPM, you pretty much have
that code in place already.

There are lots of ways to get it done. No one way is the 'right' way.
But I'd just let the timer run, set a count down the interrupt will
tick, and handle that counter in the main loop as required.

Best, Dan.

(I've been working on and off with Daniel to get the USB thing working
with launchpad/rf2500/windows. I'm starting to think the easiest way
from here is just use CCS for those boards. I'm about to plunge into the
5100 chip and may learn enough to go back on this. But by then, someone
else may have nailed it. So far, I've only made it work with pure TTY
devices like the ez.

It seems kinda self defeting that TI won't just support a plain windows
driver for third party on the launchpad. After all, I thought they
pushed it for the low end market. But then, that market may find more
than they need with CCS and when they need more, they buy the CCS
license. The way the world works...)

Beginning Microcontrollers with the MSP430

Reply by old_cow_yellow February 9, 20112011-02-09
Dan,

You are right. But for WDTCTL and other registers with "password", there is another wrinkle. Examples:
----
WDTCTL = WDT_MRST_32 + ~WDTHOLD;
is the same as WDTCTL = 0x5983; and will cause a WDT password violation reset.
-----
WDTCTL = ~WDTHOLD;
is the same as WDTCTL = 0xFF7F; and will also cause the same reset.
-----
WDTCTL &= ~(anything);
WDTCTL |= (anything);
will cause reset too, no matter what (anything) is.
-----
WDTCTL ^= 0x3300 | (8_bit_mask);
will flip those (8_bit_mask). Password will be correct.
=====
--OCY

--- In m..., Dan Bloomquist wrote:
>
> Dan Bloomquist wrote:
> > RyanK wrote:
> >
> >> WDTCTL = WDT_MRST_32 + ~WDTHOLD; //WDTPW + /* Enable watchdog */
> >>
> >>
> > Your line is the same as:
> >
> > WDTCTL = ~WDTHOLD;
> >
> >
> And a perfect example of thinking 'or' and using 'plus'. It is the same
> when using 'or'. It is something completely unexpected when using
> 'plus'. I was bit by my warning!
>
> Best, Dan.
>

Reply by Dan Bloomquist February 9, 20112011-02-09
Dan Bloomquist wrote:
> RyanK wrote:
>
>> WDTCTL = WDT_MRST_32 + ~WDTHOLD; //WDTPW + /* Enable watchdog */
>>
>>
> Your line is the same as:
>
> WDTCTL = ~WDTHOLD;
>
>
And a perfect example of thinking 'or' and using 'plus'. It is the same
when using 'or'. It is something completely unexpected when using
'plus'. I was bit by my warning!

Best, Dan.

Reply by old_cow_yellow February 9, 20112011-02-09
Aside from what Dan said. I suspect that were something missing.

Did you install the 32kHz crystal (or the equivalent)? If not, did you change the BCSCTL3 register?

Since the cell-phone charger does not have "Intel Inside" or "Microsoft innovation", it probably does not generate enough EMI to make your ACLK tick. Try attach a foot of wire to the XIN pin and bring it close to something with "Intel Inside" or a micro-wave oven.

-OCY

--- In m..., "RyanK" wrote:
>
> Code for reference. As it is it works when connected to the debug console but not without.
>
> //#include // Headers for specific device
> #include "msp430g2231.h"
> #include "HD44780LIB.h"
> #include
> #include "stdbool.h" //bool istrueorfalse; test if true or false
>
> #define Cool BIT3 // P3.3
> // constants declared here
> bool ADCDone; // ADC Done flag
> unsigned int ADCValue; // Measured ADC Value
> unsigned int ADCValueA; // Measured ADC Value Average
> unsigned int T1 = 400;
> unsigned int T2 = 400;
> unsigned int T3 = 400;
> unsigned int TempTemp = 40;
> unsigned int Mode = 0;
> unsigned int TargetTemp = 400;
> unsigned int VarTemp = 10;
> unsigned int CurrentTemp;
> unsigned int ShortCycleTime = 5000;
> unsigned int CycleDelay = 5000;
> unsigned int DelayCount = 4;//120;
> unsigned int DelayTemp = 0;
> //unsigned int TimeOutVal = 2000; // when to exit out of setup mode
> bool OkToRun = false; // Boolean 1 is true 0 is false
> bool Cooling = false; // Boolean 1 is true 0 is false
> char msg[] = "STARTUP";
>
> void itoa2(int n, char s[]);
> void reverse(char s[]);
> void Single_Measure(unsigned int chan);
> void Single_Measure_REF(unsigned int chan, unsigned int ref);
>
> HD44780 theHD44780;
> void setup(){
> P1OUT &= ~0x40; //Turnoff led
> P1DIR |= 0x40; //set dir for led2 out
> // P1OUT |= 0x40; // turn on
> // P1OUT |= 0x40; //turn on
>
> // P1OUT &= ~0x40; //Turnoff led
> // P1OUT ^= 0x40; //toggle led2
> WDTCTL = WDTPW+WDTHOLD; // Stop the dog
> WDTCTL = WDT_ADLY_1000; // Set Watchdog Timer interval
> IE1 |= WDTIE; // Enable WDT interrupt
> // WDTCTL = WDT_MRST_32 + ~WDTHOLD; //Enable WatchDog Timer
> __bis_SR_register(GIE);
> HD44780_init(&theHD44780,4,5,0,1,2,3);
> HD44780_begin(&theHD44780,16, 2);
> Single_Measure_REF(INCH_7, 0); //REF2_5V
> Cooling = false;
> OkToRun = false;
> }
> void loop() {
> // P1OUT ^= 0x40; //toggle led2
>
> delayMilliseconds(100);
>
> itoa2 (DelayTemp , msg); //Mode
> HD44780_clear(&theHD44780);
> HD44780_print_string(&theHD44780, msg);
> HD44780_print_string(&theHD44780, ".");
>
> if (!ADCDone)
> {
> HD44780_print_string(&theHD44780, "F");
> }
>
> if(ADCDone) // If the ADC is done with a measurement
> {
> ADCDone = false; // Clear flag
> Single_Measure(INCH_7); //REF2_5V
> }
>
> ADCValueA= (T1+T2+T3+ADCValue+(ADCValueA * 0x10))/0x14;
> CurrentTempCValueA;// / 0x10; //converts back to degrees hopefully
> itoa2(ADCValueA, msg);
> HD44780_print_string(&theHD44780, msg);
>
> // ******************************************************************8
> //**************************************************************
> if (Cooling){
> HD44780_print_string(&theHD44780, "C");
> if (CurrentTemp > TargetTemp+VarTemp){
> Cooling = false;
> OkToRun = false;
> WDTCTL = WDT_MRST_32 + ~WDTHOLD; //WDTPW + /* Enable watchdog */
> //P1OUT |= 0x40; //turn on
> P1OUT &= ~0x40; //Turnoff led
> //Cool = 0 //toggle relayoutput off
> // reset delay timer to 0 and start
> }
> }
>
> if (!Cooling){
> HD44780_print_string(&theHD44780, "NC");
> if (CurrentTemp < (TargetTemp-VarTemp)){
> if (OkToRun){
> //OkToRunse;
> Cooling = true;
> DelayTemp=0;
>
> P1OUT |= 0x40; //turn on
> //Cool = 0 //toggle relayoutput on
> }
> }
> }
>
> if (Mode==0){
> //Update display MODE# _ _ _ TempA TempB _ F
> }
> }
> /* itoa: convert n to characters in s */
> void itoa2(int n, char s[]) {
> int i, sign;
> if ((sign = n) < 0) /* record sign */
> n = -n; /* make n positive */
> i = 0;
> do { /* generate digits in reverse order */
> s[i++] = n % 10 + '0'; /* get next digit */
> } while ((n /= 10) > 0); /* delete it */
> if (sign < 0)
> s[i++] = '-';
> s[i] = '\0';
> reverse(s);
> }
>
> /* reverse: reverse string s in place */
> void reverse(char s[])
> {
> int i, j;
> char c;
>
> for (i = 0, j = strlen(s)-1; i > c = s[i];
> s[i] = s[j];
> s[j] = c;
> }
> }
>
> //* Reads ADC 'chan' once using an internal reference, 'ref' determines if the
> //* 2.5V or 1.5V reference is used.
> void Single_Measure_REF(unsigned int chan, unsigned int ref)
> {
> ADC10CTL0 &= ~ENC; // Disable ADC
> ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ref + ADC10IE; // Use reference,
> // 64 clock ticks, internal reference on
> // ADC On, enable ADC interrupt, Internal = 'ref'
> ADC10CTL1 = ADC10SSEL_3 + chan; // Set 'chan', SMCLK
> __delay_cycles (128); // Delay to allow Ref to settle
> ADC10CTL0 |= ENC + ADC10SC; // Enable and start conversion
> }
> //* Reads ADC 'chan' once using AVCC as the reference.
> void Single_Measure(unsigned int chan)
> {
> //ADC10CTL0 &= ~ENC; // Disable ADC
> //ADC10CTL0 = ADC10SHT_3 + ADC10ON + ADC10IE; // 16 clock ticks, ADC On, enable ADC interrupt
> ADC10CTL1 = ADC10SSEL_3 + chan; // Set 'chan', SMCLK
> ADC10CTL0 |= ENC + ADC10SC; // Enable and start conversion
> }
>
> //* ADC interrupt routine. Pulls CPU out of sleep mode for the main loop.
> #pragma vectorC10_VECTOR
> __interrupt void ADC10_ISR (void)
> { ADCDone = true; // Sets flag for main loop.
> T3=T2;
> T2=T1;
> T1CValue;
> ADCValue = ADC10MEM; // Saves measured value.
> }
>
> // Watchdog Timer interrupt service routine
> #pragma vector=WDT_VECTOR
> __interrupt void watchdog_timer(void)
> {
> DelayTemp++;
> if (DelayTemp > DelayCount)
> {OkToRun=true;
> WDTCTL = WDTPW + WDTHOLD; //WDTCTL = WDTPW+WDTCNTCL; /* Stop watchdog timer */
> DelayTemp=0;
> }
> }
> --- In m..., "RyanK" wrote:
> >
> > So I have some code running well when in debug mode connected to my computer. I then unplug the usb cable from the computer and plug it into a wall usb charger and the code behaves differently. Still using the launchpad, checked the voltage and its correct. Several if statements as well as the watchdog timer setup as an interval timer are not working. Where should I start with trying to work through this?
> >
> > I tried removing the programming jumpers leaving the VCC jumper in place with no difference.
>

Reply by Dan Bloomquist February 8, 20112011-02-08
RyanK wrote:
> WDTCTL = WDT_MRST_32 + ~WDTHOLD; //WDTPW + /* Enable watchdog */
>
I thought I'd check, never tried it. But I plugged my launchpad into my
wifes mp3 supply, it works.

I don't know if that line, (I didn't check all the code or what it might
mean), could be some of your troubles.

But reg= ~SOME_FLAG is going to turn 'all' but that flag on.

WDTCTL&= ~WDTHOLD;

will shut just that flag off. Your line is the same as:

WDTCTL = ~WDTHOLD;
Because WDT_MSRT_32 is one of the flags in ~WDTHOLD

Another thing you may want to do is stop using the plus (+) where you
really mean or (|). It can create the same kind of troubles

Turn flags on:
reg|= ONE | FOUR;

Turn flags off:
reg&= ~( TWO | FIVE );

Best, Dan.

Reply by RyanK February 8, 20112011-02-08
Code for reference. As it is it works when connected to the debug console but not without.

//#include // Headers for specific device
#include "msp430g2231.h"
#include "HD44780LIB.h"
#include
#include "stdbool.h" //bool istrueorfalse; test if true or false

#define Cool BIT3 // P3.3
// constants declared here
bool ADCDone; // ADC Done flag
unsigned int ADCValue; // Measured ADC Value
unsigned int ADCValueA; // Measured ADC Value Average
unsigned int T1 = 400;
unsigned int T2 = 400;
unsigned int T3 = 400;
unsigned int TempTemp = 40;
unsigned int Mode = 0;
unsigned int TargetTemp = 400;
unsigned int VarTemp = 10;
unsigned int CurrentTemp;
unsigned int ShortCycleTime = 5000;
unsigned int CycleDelay = 5000;
unsigned int DelayCount = 4;//120;
unsigned int DelayTemp = 0;
//unsigned int TimeOutVal = 2000; // when to exit out of setup mode
bool OkToRun = false; // Boolean 1 is true 0 is false
bool Cooling = false; // Boolean 1 is true 0 is false
char msg[] = "STARTUP";

void itoa2(int n, char s[]);
void reverse(char s[]);
void Single_Measure(unsigned int chan);
void Single_Measure_REF(unsigned int chan, unsigned int ref);

HD44780 theHD44780;
void setup(){
P1OUT &= ~0x40; //Turnoff led
P1DIR |= 0x40; //set dir for led2 out
// P1OUT |= 0x40; // turn on
// P1OUT |= 0x40; //turn on

// P1OUT &= ~0x40; //Turnoff led
// P1OUT ^= 0x40; //toggle led2
WDTCTL = WDTPW+WDTHOLD; // Stop the dog
WDTCTL = WDT_ADLY_1000; // Set Watchdog Timer interval
IE1 |= WDTIE; // Enable WDT interrupt
// WDTCTL = WDT_MRST_32 + ~WDTHOLD; //Enable WatchDog Timer
__bis_SR_register(GIE);
HD44780_init(&theHD44780,4,5,0,1,2,3);
HD44780_begin(&theHD44780,16, 2);
Single_Measure_REF(INCH_7, 0); //REF2_5V
Cooling = false;
OkToRun = false;
}
void loop() {
// P1OUT ^= 0x40; //toggle led2

delayMilliseconds(100);

itoa2 (DelayTemp , msg); //Mode
HD44780_clear(&theHD44780);
HD44780_print_string(&theHD44780, msg);
HD44780_print_string(&theHD44780, ".");

if (!ADCDone)
{
HD44780_print_string(&theHD44780, "F");
}

if(ADCDone) // If the ADC is done with a measurement
{
ADCDone = false; // Clear flag
Single_Measure(INCH_7); //REF2_5V
}

ADCValueA= (T1+T2+T3+ADCValue+(ADCValueA * 0x10))/0x14;
CurrentTempCValueA;// / 0x10; //converts back to degrees hopefully
itoa2(ADCValueA, msg);
HD44780_print_string(&theHD44780, msg);

// ******************************************************************8
//**************************************************************
if (Cooling){
HD44780_print_string(&theHD44780, "C");
if (CurrentTemp > TargetTemp+VarTemp){
Cooling = false;
OkToRun = false;
WDTCTL = WDT_MRST_32 + ~WDTHOLD; //WDTPW + /* Enable watchdog */
//P1OUT |= 0x40; //turn on
P1OUT &= ~0x40; //Turnoff led
//Cool = 0 //toggle relayoutput off
// reset delay timer to 0 and start
}
}

if (!Cooling){
HD44780_print_string(&theHD44780, "NC");
if (CurrentTemp < (TargetTemp-VarTemp)){
if (OkToRun){
//OkToRunse;
Cooling = true;
DelayTemp=0;

P1OUT |= 0x40; //turn on
//Cool = 0 //toggle relayoutput on
}
}
}

if (Mode==0){
//Update display MODE# _ _ _ TempA TempB _ F
}
}
/* itoa: convert n to characters in s */
void itoa2(int n, char s[]) {
int i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}

/* reverse: reverse string s in place */
void reverse(char s[])
{
int i, j;
char c;

for (i = 0, j = strlen(s)-1; i c = s[i];
s[i] = s[j];
s[j] = c;
}
}

//* Reads ADC 'chan' once using an internal reference, 'ref' determines if the
//* 2.5V or 1.5V reference is used.
void Single_Measure_REF(unsigned int chan, unsigned int ref)
{
ADC10CTL0 &= ~ENC; // Disable ADC
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ref + ADC10IE; // Use reference,
// 64 clock ticks, internal reference on
// ADC On, enable ADC interrupt, Internal = 'ref'
ADC10CTL1 = ADC10SSEL_3 + chan; // Set 'chan', SMCLK
__delay_cycles (128); // Delay to allow Ref to settle
ADC10CTL0 |= ENC + ADC10SC; // Enable and start conversion
}
//* Reads ADC 'chan' once using AVCC as the reference.
void Single_Measure(unsigned int chan)
{
//ADC10CTL0 &= ~ENC; // Disable ADC
//ADC10CTL0 = ADC10SHT_3 + ADC10ON + ADC10IE; // 16 clock ticks, ADC On, enable ADC interrupt
ADC10CTL1 = ADC10SSEL_3 + chan; // Set 'chan', SMCLK
ADC10CTL0 |= ENC + ADC10SC; // Enable and start conversion
}

//* ADC interrupt routine. Pulls CPU out of sleep mode for the main loop.
#pragma vectorC10_VECTOR
__interrupt void ADC10_ISR (void)
{ ADCDone = true; // Sets flag for main loop.
T3=T2;
T2=T1;
T1CValue;
ADCValue = ADC10MEM; // Saves measured value.
}

// Watchdog Timer interrupt service routine
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
DelayTemp++;
if (DelayTemp > DelayCount)
{OkToRun=true;
WDTCTL = WDTPW + WDTHOLD; //WDTCTL = WDTPW+WDTCNTCL; /* Stop watchdog timer */
DelayTemp=0;
}
}
--- In m..., "RyanK" wrote:
>
> So I have some code running well when in debug mode connected to my computer. I then unplug the usb cable from the computer and plug it into a wall usb charger and the code behaves differently. Still using the launchpad, checked the voltage and its correct. Several if statements as well as the watchdog timer setup as an interval timer are not working. Where should I start with trying to work through this?
>
> I tried removing the programming jumpers leaving the VCC jumper in place with no difference.
>

Reply by Bob February 8, 20112011-02-08
Sorry Ryan, I don't know CCS4. I assumed, wrongly, IAR.

Bob

--- In m..., "RyanK" wrote:
>
> Where can I determine which mode i'm running in? I didn't mention it but i've been using CCS4.
>
> --- In m..., "Bob" wrote:
> >
> > --- In m..., "RyanK" wrote:
> > >
> > > So I have some code running well when in debug mode connected to my computer. I then unplug the usb cable from the computer and plug it into a wall usb charger and the code behaves differently. Still using the launchpad, checked the voltage and its correct. Several if statements as well as the watchdog timer setup as an interval timer are not working. Where should I start with trying to work through this?
> > >
> > > I tried removing the programming jumpers leaving the VCC jumper in place with no difference.
> > >
> >
> > One possibility: If, when debugging on PC, you're running in "simulator" mode, your interrupts, etc. will not be active, thus you're not debugging the hardware, just code that's outside of any interrupts. Check to see if you're debugging the device and not the simulator.
>

Reply by RyanK February 8, 20112011-02-08
Where can I determine which mode i'm running in? I didn't mention it but i've been using CCS4.

--- In m..., "Bob" wrote:
>
> --- In m..., "RyanK" wrote:
> >
> > So I have some code running well when in debug mode connected to my computer. I then unplug the usb cable from the computer and plug it into a wall usb charger and the code behaves differently. Still using the launchpad, checked the voltage and its correct. Several if statements as well as the watchdog timer setup as an interval timer are not working. Where should I start with trying to work through this?
> >
> > I tried removing the programming jumpers leaving the VCC jumper in place with no difference.
> > One possibility: If, when debugging on PC, you're running in "simulator" mode, your interrupts, etc. will not be active, thus you're not debugging the hardware, just code that's outside of any interrupts. Check to see if you're debugging the device and not the simulator.
>

Reply by RyanK February 8, 20112011-02-08
I'll post the code later tonight to help illustrate but i'll outline the function below.

Its a refrigerator controller, ACD used to read temp though a Thermistor. LCD display to output temperature and status (cooling, heating, interlock).
The interlock is a mode that prevents the compressor from turning on within 5 minutes of turning off. This interlock function is where i am using the watchdog interrupt.

The main loop reads the ADC, displays it on the lcd compares it to the setpoint+10 and if above turns on the fridge. Once the fridge cools below the setpoint-10 it starts the watchdog interval timer. Each time the interrupt occurs it increments a variable and checks if it is greater than count value. I then output the value to the LCD to monitor its process. Once above the count value the watchdog is stopped and sets a flag that allows the fridge to be turned on again.

Everything works as intended when the computer is connected and I click on the debug button.

When I remove the computer and try to power the launchpad from a usb wall charger the temperature updates correctly but none of the comparisons or the watchdog does not seem to start as the value doesn't increment on the display.

As i said i'll post the code later tonight but thats the general outline and more detail of what isn't working.

--- In m..., "old_cow_yellow" wrote:
>
> --- In m..., "RyanK" wrote:
> >
> > ... Several if statements as well as the watchdog timer setup
> > as an interval timer are not working. ...
> > How do you know that?
>
> Does you code try to read S2?
>
> Did you try to press S1?
>

Reply by old_cow_yellow February 8, 20112011-02-08
--- In m..., "RyanK" wrote:
>
> ... Several if statements as well as the watchdog timer setup
> as an interval timer are not working. ...
>

How do you know that?

Does you code try to read S2?

Did you try to press S1?