Jump to content
yyrkoon

msp430G2553 WDT

Recommended Posts

His implementation is very simple but not so flexible. You can find a more complete c++ template implementation here:

 

https://github.com/RickKimball/fabooh/blob/master/examples/serial/ascii_table_iostream/ascii_table_iostream.cpp - ascii table dump using operator insertion or standard function calls

https://github.com/RickKimball/fabooh/tree/master/examples/math .. sine table prints using cordic, fixed math and floats

 

fabooh support eusci, usci, software only (on any pin) with multiple instances and finally timer based serial.

Your code needs a manual in order to use it, and you've not provided one that I can see. Would love to give it a go, but I will not spend time guessing how it works. You need an *MD file to quickly and succinctly describe how one goes about using your code. *IF* you care if people use it or not. If you do not care, then leave it as it is . . .

Share this post


Link to post
Share on other sites

To be honest I don't think it is that useful anymore.  TI has little interest in the smaller chips.  Their approach is go big or go home. Their recent marketing approach seem to be, let us force feed TI-RTOS to everyone.  People using the smaller chips probably already have their favorite mode of coding.   I threw this code out there to show what is possible and also to give some context to how you arrived at your simple and small implementation. Fabooh has had little interest so it isn't worth documenting other than providing the example folder.  That is enough for people interested in trying some c++ templates code that is optimized for the msp430-gcc.  Most people really want full Arduino compatibility or they want to do their own thing in C.  I thought Zeke and others might find it interesting.  To build the examples you just type:

$ git clone https://github.com/RickKimball/fabooh.git
$ cd fabooh
$ make clean all # at the top level directory

I assume you are using linux and an msp430g2553 v1.5 launchpad. I don't try to build this stuff on windows. Although if you have the linux tools installed and msp430-gcc in your path it should work.

 

If you want to use a specific example just change to that directory and type:

$ cd fabooh/examples/serial/ascii_table
$ make clean all install

The easiest way to start your own new program is find an example you like and copy that directory to a new one with a new name

$ cd fabooh/examples/serial
$ cp -rv ascii_table my_app
$ cd my_app
$ mv ascii_table.cpp my_app.cpp
$ sed -e 's/ascii_table/my_app/g' Makefile > makefile
$ mv makefile Makefile
$ make clean all install

BTW: I don't disagree with your solution.  Your approach of hard coding it to do what you want is a perfectly reasonable approach.

I was just responding to your comment that you didn't remember where to find the serial print stuff I wrote.

Share this post


Link to post
Share on other sites

To be honest I don't think it is that useful anymore.  TI has little interest in the smaller chips.  Their approach is go big or go home. Their recent marketing approach seem to be, let us force feed TI-RTOS to everyone.  People using the smaller chips probably already have their favorite mode of coding.   I threw this code out there to show what is possible and also to give some context to how you arrived at your simple and small implementation. Fabooh has had little interest so it isn't worth documenting other than providing the example folder.  That is enough for people interested in trying some c++ templates code that is optimized for the msp430-gcc.  Most people really want full Arduino compatibility or they want to do their own thing in C.  I thought Zeke and others might find it interesting.  To build the examples you just type:

$ git clone https://github.com/RickKimball/fabooh.git
$ cd fabooh
$ make clean all # at the top level directory

I assume you are using linux. I don't try to build this stuff on windows. Although if you have the linux tools installed and msp430-gcc in your path it should work.

 

If you want to use a specific example just change to that directory and type:

$ cd fabooh/examples/serial/ascii_table
$ make clean all install

The easiest way to start your own new program is find an example you like and copy that directory to a new one with a new name

$ cd fabooh/examples/serial
$ cp -rv ascii_table my_app
$ cd my_app
$ mv ascii_table.cpp my_app.cpp
$ sed -e 's/ascii_table/my_app/g' Makefile > makefile
$ mv makefile Makefile
$ make clean all install

BTW: I don't disagree with your solution.  Your approach of hard coding it to do what you want is a perfectly reasonable approach.

I was just responding to your comment that you didn't remember where to find the serial print stuff I wrote.

Yeah, I'm in project mode, not experimenters mode. Thanks for the "manual" :)

 

Whats more, I think I blew my UART on the launchpad somehow. nothing is working. Not even energias serial monitor. Granted, Energias serial examples are so pitifully broken . . .*someone* really needs to clean Energias examples up, and present them in a way that it is obvious what works with what.

Share this post


Link to post
Share on other sites

Does this look normal ? Second launchpad also not working so now I'm forced to believe it is Windows being a piece of s . . . as usual.

 

MSPDebug version 0.22 - debugging tool for MSP430 MCUs
Copyright © 2009-2013 Daniel Beer <dlbeer@gmail.com>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

MSP430_Initialize: USB
Firmware version is 20409001
MSP430_VCC: 3000 mV
MSP430_OpenDevice
MSP430_GetFoundDevice
Device: MSP430G2xx3 (id = 0x00de)
2 breakpoints available
MSP430_EEM_Init
Chip ID data: 25 53
Erasing...
Programming...
Writing  600 bytes at c000 [section: .text]...
Writing   26 bytes at c258 [section: .rodata]...
Writing    2 bytes at c272 [section: .data]...
Writing   32 bytes at ffe0 [section: .vectors]...
Done, 660 bytes total
MSP430_Run
MSP430_Close

Process returned 0 (0x0)   execution time : 2.237 s
Press any key to continue.
 

Share this post


Link to post
Share on other sites

Anyone care to remind me why the f I bother with Windows ? Apprently Windows lost it's mind AGAIN, and I had to search the web for some secrete arcane magic hand waving technique to get the dammed serial working again.

 

Turns out you have to open the port with the launchpad plugged in but at a different incorrect baud rate. THEN, you switch it back, and reset the terminal . . . jesus . . .

Share this post


Link to post
Share on other sites

Here is a fabooh version of your code:
 
https://github.com/RickKimball/fabooh/tree/master/examples/serial/feed_the_dog
 
Note: I set this up so you can try all the different serial implementations. Because you said your uart was broken I compiled it for software only right now.  You can change that be modifying the #if that selects which serial implementation  It only needs 466 bytes.

/**
 * feed_the_dog.cpp - an msp430g2xxx specific watchdog timer example
 *
 * msp430-size msp430g2553in20_release/feed_the_dog.elf
 *   text     data      bss      dec      hex  filename
 *    432        0        6      438      1b6  msp430g2553in20_release/feed_the_dog.elf
 */

#include <fabooh.h>
#include <main.h>
#include <serial.h>

volatile unsigned int count = 0;
sw_serial_t<9600, CPU::frequency, TX_PIN, NO_PIN> Serial;

inline void setup(void)
{
  Serial.begin();

  /* ADC */
  P1_5::PSEL();
  ADC10CTL0 &= ~ENC;
  ADC10CTL1 = INCH_5 | ADC10DIV_3 ;
  ADC10CTL0 = SREF_0 | ADC10SHT_3 | ADC10ON;
  ADC10AE0 |= BIT5;

  /* Timer1 A0*/
  TA1CCR0 = (CPU::frequency*.010 )/8;     // Count overflow frequency ~10ms
  TA1CTL = TASSEL_2 | ID_3 | MC_1;        // SMCLK / 8  upmode
  TA1CCTL0 = CCIE;

  __enable_interrupt();
  WDTCTL = WDTPW | WDTCNTCL;              // Enable WDT
  Serial << "\r\nreset...\n";
}

void loop()
{
  unsigned sample;

  LPM0;
  WDTCTL = WDTPW | WDTCNTCL;
  
  if (count > 100) {                      // ~1 Second
    count = 1;
    __delay_cycles(128);                  // Let the pins settle
    ADC10CTL0 |= ENC | ADC10SC;           // Sampling and conversion start
    while(ADC10CTL1 & ADC10BUSY) {
      LPM0;                               // Sleep until ADC done
    }
    sample = ADC10MEM;

    Serial << sample << "    \r";
  }
}

__attribute__( (interrupt(TIMER1_A0_VECTOR)) )
void TIMER1_A0_ISR(void)
{
  count++;

  if ( !(ADC10CTL1 & ADC10BUSY) ) {
  	LPM0_EXIT;
  }
}

__attribute__( (interrupt(ADC10_VECTOR)) )
void ADC10_ISR(void)
{
  LPM0_EXIT;
}
 

I've also attached a binary in case you just want to try it without having to setup fabooh:

ftd_bin.zip

 

 
-rick

Share this post


Link to post
Share on other sites

@@Rickta59

 

Looks pretty cool, but I do have one gripe. You're code definitely looks more flexible than mine, but definitely at the cost of readability. I know you live and breathe C++, but I've been attempting to steer myself clear of C++ lately. Not because I think it's bad, or incapable. Because I think that C++ is too complex, and requires too much energy to keep up on. By it's self it would not be a problem, but when constantly learning hardware for( i dont know how many ) embedded platforms . . . it can be a hindrance.

 

Don't get me wrong though I do appreciate you sharing. Thank you !

Share this post


Link to post
Share on other sites

@@Rickta59

 

Also I love seeing stuff like this:

if (count > 100) { // ~1 Second
P1_6::toggle();
count = 1;
__delay_cycles(128);
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
while (ADC10CTL1 & ADC10BUSY) { // sleep and wait for completion
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
    WDTCTL = WDTPW | WDTCNTCL;
}

Which is tweaks of the code I wrote, but with subtle, and important differences. For instance, I was considering how I would factor out that __delay_cycle() entirerly. Then waiting for the ADC hardware to complete a sample, and sleeping the whole time . . . Granted, I'm not sure how that would impact my control loop. I'm attempting to keep a timing mechaism that will allow me to use base 10 math in order to keep timing. Granted, I'm not really sure how important all that really is. I do need to be able to detect a "wiggle" in an IO for various things, which I'm still thinking on how I'm going to achieve that . . .

 

Basically, I'm working one problem at a time, until I get everything I need worked in. Then perhaps I can tweak until I'm happy with the code ? I have hardware here now for the project this is going into. So I probably have about a week or two before I have to show a working prototype.

Share this post


Link to post
Share on other sites

you need the __delay_cycle() to let the pins settle so they are quiet.  I wasn't doing anything to try and modify the timing.  I'm using:

while (ADC10CTL1 & ADC10BUSY) {       // sleep and wait for completion
      asm("nop");
}

To wait for the adc sample to finish.  The better way to do it would be to have an ADC ISR wake up the chip. Just start the ADC capture and then sleep. Have the ISR do an LPM_EXIT.  When it comes out of sleep just read the sample.  Of course you would have to disable the TIMER while waiting for the ADC to finish.

Share this post


Link to post
Share on other sites

you need the __delay_cycle() to let the pins settle so they are quiet.  I wasn't doing anything to try and modify the timing.  I'm using:

while (ADC10CTL1 & ADC10BUSY) {       // sleep and wait for completion
      asm("nop");
}

To wait for the adc sample to finish.  The better way to do it would be to have an ADC ISR wake up the chip. Just start the ADC capture and then sleep. Have the ISR do an LPM_EXIT.  When it comes out of sleep just read the sample.  Of course you would have to disable the TIMER while waiting for the ADC to finish.

Yeah, I was afraid of that. The timer interrupt is the most important, so it has to stay. I have one GPI, that I have to be able to detect a few different situations from the outside, and the only way I know how to do that is to time how long the pin has been pulled high, or low. Perhaps even "wiggle" as in multiple toggles in a set time frame. So I'm guessing I'd have to disable the port interrupts too, and that definitely, no way, can't happen.

 

So . . . I suppose I have to think of something, that does not involve changing the interrupts I have now.

Share this post


Link to post
Share on other sites

I modified the example to show what I meant.

Yeah I saw that. Looks awesome, wish I could use it now. But for this project I can't use it unfortunately :(

Share this post


Link to post
Share on other sites

@@Rickta59

 

I think I misunderstood what you meant by what I should do. Looking at your example, doing thing s that way I would not have to disable my timer interrupt. Something like that might work perfectly.

Share this post


Link to post
Share on other sites

An alternative is to set a semaphore in the ISR and check on it on exit from LPM. ADC10BUSY is a kind of semaphore but as complexity is added to the code I would not use that as it may lead to problems down the road.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×