20 July 2010

Tutorial 08-a: The Beating Heart (BCS+ Part I)

With the basics behind us, we can jump into some of the more advanced (and far more interesting!) topics to learn how to use the MSP430 microcontroller.  The goal of this tutorial series is to examine the various peripherals available on the MSP430 devices and how to use them.  Along the way, we'll look at the concepts of interrupts and low power modes as well.  To follow this tutorial, it is extremely helpful to have a copy of the Family User's Guide and Datasheets for the specific device you are using.  I printed these out (including the 600+ page User's Guide) and had them bound for easy access, but an electronic copy will work fine.  The first peripheral we'll look at is the Basic Clock System + (BCS+) used in the MSP430x2xx Family, including the Value Line chips compatible with the LaunchPad platform.  This system is detailed in Chapter 5 of the x2xx Family User's Guide.

 We've seen in our analogy to a town that we can issue different commands and control different things easily in the MSP430.  Just as in any town, if the parts aren't working in conjunction then everything winds up in a big mess.  When does this switch get flipped?  Does it happen before or after that event?  What order do I do things, and when?  Every town needs a clock, and a microcontroller depends on one.

The 3 Clocks
Each family of MSP430 has a slightly different clock system, though many of the principles are the same for each.  The x2xx family uses the BCS+ system, which provides the MSP430 with three separate clocks that can run as quickly as 16 MHz in particular conditions.  The reason we have three clocks instead of just one or even two is to compromise between systems that need speed and the ability to minimize power consumption, one of the real hallmarks of the MSP430.  Faster clocks consume more power, so to really reduce the power used we need slower clocks.  But some functions need to respond and conclude quickly, so we also need fast clocks.  You can design around the use of a single clock, but having the flexibility of three is powerful.  Let's look at the three clocks available in BCS+:

  • MCLK:  This is the Master Clock, the one that drives the processor and times the commands in your program.  This is typically a high frequency clock, but can be configured for low frequencies if needed.
  • SMCLK: The Sub-Main Clock is a secondary clock that is often used by other peripherals.  It can be the same frequency as MCLK or different, depending on the application.
  • ACLK: The Auxilliary Clock is usually timed outside the MSP430 and is typically used for peripherals.  Often, this is a low frequency clock, but can also be used at high frequencies when desired.
The 4 Sources
There are also up to four sources available in BCS+ to drive each of the three clocks:
  • LFXT1CLK:  The name of this source implies its use with a low-frequency crystal, and this is often the case.  A 32,768 Hz crystal can be connected to your MSP430 for low-power, high-accuracy timing.  In some x2xx devices, this source also has a high frequency mode that can use crystals from 400 kHz to 16 MHz, assuming the chip is powered with a large enough voltage to handle the frequency.  In addition, other resonators and external signals can be used for this source.
  • XT2CLK:  Again, this source is named for its implied use with a second crystal, but in this case only a high frequency crystal.  It can also use other resonators and external signals.  This source is not available on every x2xx device.  (See page 5-2 of the x2xx Family User's Guide to see which devices use XT2.)
  • DCOCLK:  The internal source is the digitally controlled oscillator.  Though not as accurate and stable as crystal sources, the DCO is still quite good and can be configured to operate at a wide range of frequencies.
  • VLOCLK:  The MSP430 includes a second internal oscillator for very-low power, very-low frequency applications.  The VLO can run slower than the LFXT1 watch crystal, and typically is used at about 12 kHz.  This source is not available in all x2xx devices.  (Refer to 5-2 in the User's Guide.)
Each clock can also divide the frequency by which it's sourced by a factor of 2, 4, or 8.  In addition, many peripherals can further divide their clock by the same factors, giving a large number of possible frequencies available from just one source.  While MCLK and SMCLK can use any of the four sources, ACLK uses only LFXT1 or VLO.  The default configuration for MCLK and SMCLK is to use the DCO at about 1.1 MHz, and for ACLK is to use LFXT1.  In the coming parts for Tutorial 08, we'll look at each source and how to configure them properly.  Because it's in every MSP430 device, we'll start with the DCO before taking a look at using crystals.

So the BCS+ provides us three separate clocks with 32 possible ways of sourcing them.  The clocks can be divided for operation of different peripherals individually.  These varied combinations provide for nearly any conditions needed for an MSP430 project.  We should not neglect, however, to note that TI has gone to great effort to make the clock system very reliable; even the VLO and DCO are very well made, accurate, and stable.  For precision timing, nothing can surpass well-designed crystal control, but the internal clocks do a great job, and can even change configuration in the middle of a program.  Such power available without much sacrifice for quality is one of the real benefits of the MSP430 design.

Look forward to the next post, where we'll examine how we configure the DCO for different operating modes in the MSP430!

19 July 2010

Disclaimer on Changing Chips

Just a word of caution; the MSP430G2231 in my LaunchPad was seated pretty firmly.  I've written my tutorial code for the G2211, and so following it exactly requires changing the chips out.  If you're not careful about it, you can really mangle the pins on the G2231 when you try to pull it out.  Get yourself an IC extractor, or pry at it carefully and evenly from underneath.  If you do end up bending some of the pins, you should be able to bend them back into place if you're careful.  If you break off a pin... well, consider yourself warned.

Anyone have some good tips on pulling out DIPs?

Tutorial 07: Pushing Buttons

We've gotten to the point now where we can program the MSP430 and make it respond by flashing an LED or two.  While being able to change pins to outputs is useful, it's the combination of input and output that make the microcontroller so powerful.  The pushbutton is one of the simplest types of inputs, and will be very helpful for learning more about the peripherals.

There are all kinds of switches available on the market, and there are some differences in the ways they need to be attached to the MSP430.  For now we'll look at single-pole, single-throw (SPST) types, such as the momentary push-button.  The LaunchPad platform includes two of these types of buttons; one is connected to P1.3 (that's the button on the lower left of the board) and the other to the RST/SBWTDIO pin (pin 16 on the DIP).

Connecting Buttons
If you are following the tutorial using the LaunchPad, then open up a copy of the LaunchPad User's Guide and turn to page 15 to see a circuit schematic of the target section of the board.  You can see here that the two buttons are connected between their respective pins and ground.  Note also that the same pins have 47 kΩ resistors connecting them to Vcc.  To use pushbuttons in digital logic, they need to be able to provide a 1 in one state and a 0 in the other.  When the button is up, the resistor ties the pins to Vcc, pulling up the voltage to whatever level the board is powered at (in the case of the LaunchPad, it's 3.6V).  When you press the button, it closes the short to ground.  So unpressed is logic 1, and depressed is logic 0.

You can use the opposite convention as well, reversing the positions of the button and the resistor.  For obvious reasons, we call the first configuration a "pull-up resistor" and the second a "pull-down resistor".  Without these resistors, the input pin would be floating, and could take on any value between ground and Vcc, which gives inconsistent behavior for your design.  Whichever case makes more sense for your design, always remember to use the resistors to pull the open state up or down.  A larger resistor (such as the 47 kΩ used on the LaunchPad) keeps the current draw from the button low.  Ideally we only want to change the potential on the input pin and not use any power to do so.

You might recall that there are internal resistors on each of the GPIO pins for the MSP430 that can act as pull-up and pull-down resistors.  The resistance value quoted for these in the MSP430 datasheets is large enough that the current draw would not be too high, but as readers have pointed out it may not be the best practice to use these for your push-buttons, especially while prototyping and testing.

Example
With the resistors in place, using buttons in an MSP430 design is quite simple.  Let's illustrate them by writing a program that flashes the red LED on P1.0 a few times, then flashes the green LED on P1.6 a few times after the button is pressed.  Pressing the button again should return to the red LED, and so on.  For this program, we'll need to configure the two LED pins as outputs and be sure the button pin (P1.3) is configured as an input.  We'll use the technique from the Blinky program to take care of the LED delay again, so we'll need a counter as well.  A second counter will keep track of the number of times the LED flashes.

The new thing needed is an ability to tell the MSP430 to check the state of the button periodically; we call this polling.  When the program reaches the point where it is waiting for the user to push the button, it should check and recheck the button until it sees that it has been pressed.  We can do this by using a logic operation to check the value on P1IN.  Since the button is attached to P1.3, bit 3 of P1IN tells us if the button is pressed (logic 0) or unpressed (logic 1).  The other bits of P1IN could, in principle, be anything, so how can we extract just the value of bit 3?  A simple way is to use the & operator-- since x & 0 = 0 and x & 1 = x, then P1IN & BIT3 (0b00001000) will return 0b0000x000, where x is the current value of bit 3 in P1IN.  Note that the result is not either 0 or 1, but rather 0 or 0b00001000, which is also the value BIT3.  Since 0 corresponds to the pressed state, we can poll P1IN in a loop that continues while (P1IN & BIT3) == BIT3, or equivalently while (P1IN & BIT3) != 0.

I've written my own version of a program that uses this in pushy_G2211.c.  Try coding the program up yourself first, and then compare it to mine.  A couple of new techniques used in the code are the #define command in the header, and encapsulation of a re-used command in a function call.  If you're not familiar with either of these techniques, brush up on them in your favorite, reliable book on C programming.  Essentially, #define lets me rename the value BIT0 to something more descriptive-- in this case, red_LED.  Since this doesn't change the value of BIT0, it can still be used in the code, or you can even define two things to be BIT0, as you would if you had LEDs on P1.0 and P2.0 of a larger MSP430 device.  The delay() function also makes the code more readable, and illustrates the power of encapsulation.  Since a delay function is so common, I could put this into a library, and then recall it whenever I want without having to retype the same thing over and over.  I encourage you to use these and any other good coding practices as much as possible to help make your code easier to understand and reuse!

This code isn't perfect, as it can't account for all situations.  What happens if you press the button while an LED is flashing?  Since the input value only matters during the while loop, nothing.  If you have ninja reflexes and push the button in a way where the MSP430 polls it before and after the pressing, then  it never sees the button press.  And what happens if you just hold the button down?  The solution here is to use interrupts, which is a topic beyond this tutorial.  But for now, you have a rudimentary way to use buttons.

Reader Exercise 1:  Copy the code into a new CCS project and try loading Pushy into your G2211.  Step through the code with the debugger to be sure it works.  (Change the limit on count to save clicks.  Change the limit on flash too, if you're not feeling particularly patient.)  Note that to get the debugger to work with the button you need to be holding it down as you step into the next line.  Try watching the P1IN register as you step through to see the input value change.


Reader Exercise 2:  We didn't discuss the RST button on the LaunchPad; try letting the red LED blink, then push this button instead of the button on P1.3.  (You'll have to terminate the debugger to get this to work.)  What does it do?  While the LaunchPad is configured in a way where this is the only function this button can have, it's a very useful tool to have, especially if you ever need to restart you program!

Question for Readers

I just received my two LaunchPads this morning; I'm excited they're finally here!  One of the things I mentioned in an early post was that, with my PW28 target board, I put female headers in for the breakout section.  These are my reasons for having used that convention:

  • A socket can connect to a plain solid wire for quick connections to breadboards, etc.
  • In rockets, the rule of thumb is if something is disconnected, the side that remains powered should not be an exposed pin to prevent an accidental short when wires are jostled around.
  • Looks cleaner than the bare pins; no concern of something outside the circuit (eg. a meter) brushing up against a pair of pins and accidentally shorting them.
It seems many others use the opposite convention, such as in the Arduino case.  (Reader Plazma points out that other photos of the Arduino show the female convention being used.)  Ultimately, it would be nice to use the convention that is common to most users, making use of other people's designs, "shields", expansion boards and what not easy.

So what does everyone think?  Which convention would be the better one to use, male or female headers on the LaunchPad?  Why?

17 July 2010

Comments

For those who have put comments on, I apologize for not having moderated them promptly.  The blog is now set so that anyone can post without signing in, and it will notify me when I need to moderate them.  I'd like to moderate them just so I'm aware when someone says something-- I trust everyone, but I don't trust myself to go back and look.  This way I get to learn from y'all!

Also, while I've posted up the initial tutorials, they may change and edit a bit more as I read through them again and find errors.  Thanks for your patience!  My LaunchPads should be arriving on Monday, so look forward to a little more then!

Tutorial 06: Getting the Bugs Out

The debugging features of the MSP430 are one of the most helpful tools you'll have in developing your projects. Let's take a look at how to use some of the basic features here.  Load up your Blinky program and start the debugger, but this time don't push the 'Run' button, just leave it in a hold state.  Your screen should look something like the image here.  Note a few things to start.  There are six windows opened here by default. The one on the far right, the 'Cheat Sheets', gives tips and help if you need it.  You can also just close this window.  (If you really get annoyed with it, just choose Disable All Cheatsheets on that window.)

The five remaining windows are Debug, Variables (labeled Local in this screenshot), the code, Dissasembly, and a Console.  The console, again, shows results and errors that come from compiling, loading, and in some cases the code itself.  The code window should be self-explaning, but note that the void main(void) { line is highlighted and has an arrow next to it.  This shows where in the code the debugger is sitting.  When you first load code into the flash memory of the chip, it turns on and holds everything right at the start.  The variables window shows current values of code variables and (we'll see in a little while) of registers in the MSP430.  The Debug window shows where we are in the hierarchy of the project itself.  (Ours is simple, only one source file, so this window isn't as helpful right now.)

Note the collection of icons in the Debug window.  You can see the 'Run' button there.  The other important ones for this tutorial follow the 'Run' button.  There's 'Halt' (looks like a pause button, should be grayed out when the debugger holds, lights up while 'Run' grays out when the chip is running), then 'Terminate All'.  These control the debugger, like a play, pause, and start button.  Next come a series of arrows, the first of which is 'Step Into'.  We'll use that button today.  A little farther, there's an icon that looks like a chip with two cycling arrows.  This button resets the CPU in the MSP430 and sends the debugger back to the beginning.

Example
Before we start debugging our code, let's change the number of loops in our delay to 6.  You'll see why in a bit.  Scroll through the code in the code window until you find the right line, and change the count to end at 6 rather than 60000.  Up at the top of the CCS window, you'll see icons similar to what we had in the compiler environment.  Next to the 'Build Active Project' icon, there's a 'Rebuild Active Project' icon.  After you make simple changes in the code here, click that button to recompile and reload the updated code to the MSP430. (If you need to make significant changes to the code, it's easier to terminate the debugger and work in the compiler environment.)  Go ahead and tell CCS to reload the code into your MSP430, and the debugger will start over again.

Now we'll use the 'Step Into' button of the debugger to step through the code line by line.  One click of the button, and you should see the arrow move down two lines, to WDTCTL.  You may have noticed that the count variable already appeared in the Local Variables window; CCS loads that information automatically before debugging.  The value of count is probably just some random value that we won't be using.  We'll get back to that window soon.

Before we 'Step Into' the WDTCTL line, let's open up another useful window.  Go to View → Registers, and you'll see another variable window pop up with all the registers in your device.  (This feature is so useful for learning from!  We'll make extensive use of this as we learn about the MSP430 peripherals, so remember how to do this part.)  To the bottom of the list, you'll find Watchdog_Timer.  Open up this section, and you'll find the WDTCTL register.  The debugger is showing that the register currently has the hex value 0x6900.  Opening the WDTCTL register shows the individual bits.  Note that all of them are set to 0 when you power up the MSP430.  This setting uses the watchdog timer normally, and running like this would reset the CPU periodically.  Now step into the next line of our code and see what happens.

Stepping into the next line, you see the WDTHOLD turns to 1 (and turns red, signifying something changed in this clock cycle) and the value of WDTCTL is now 0x6980.  You may recall that setting the WDT requires a password of 0x5a.  When you read the password byte of WDTCTL, however, it returns 0x69.


(Want to force a reset in your code?  Try writing WDTCTL = WDTCTL.  Reading WDTCTL returns a value that is not the right password and you give the incorrect key to be able to write to the register; the MSP430 resets if this happens.)

See if you can find the P1 registers and then step into the next two lines to see what happens there.  The debugger should now be on the LED toggle line in the infinite loop.  Before we go further, change the variable window back to the local variables.  Note that count still has some random value in it.  Now, stepping into the LED toggle line, we should change P1OUT to light up the LED!  We are now at the for loop for the delay.  Step once into this; the debugger goes right back to the same line, but note the change in the value of count in the variable window.  Count increments by 1 each time you press 'Step Into'.  When it reaches count==6, the debugger moves on to the next line.  One more step brings you back to the LED toggle.  (Glad I had you change the delay to 6 instead of 60000?)  You can then step through the code to turn off the LED, delay again, then repeat as much as you wish.  At any time you can hit 'Run' and set the MSP430 off on its own.  If you want to show someone that your LaunchPad is working, don't forget to increase the value in the delay loop.  The MSP430 is fast enough that your eye won't pick up the frequency with counting up to 6.  =)

The debugger is a very useful tool, though keep in mind it won't always work for what we want it to do.  The MSP430 is designed to interface with the outside world.  While the debugger can pause the clock inside the MSP430, it can't pause the clock in our world.  Later on we'll look at what to do when you're debugging code that relies on outside timings.  But I hope you can see just how helpful the debugger can be in your project.  If you know of or discover any other features of the CCS debugger that you find very helpful, send a comment and let us know!

This post concludes the initial collection of tutorials on the MSP430.  You now have enough knowledge to be able to write a program, download the code into an MSP430, and create some basic projects.  Good luck on your next project, and join in our growing community to let people know what you're able to do and learn with the MSP430!  Come back often as I'll be posting new tutorials on the peripherals of the MSP430 soon.

Reader Exercise:  Try out the code you wrote in Tutorial 04.  Does it behave how you expected?  Use the debugger to step through it (change any delay loops to something manageable) and be sure everything runs as it should.

Tutorial 05: Loading the Program

Note:  I just received word that my LaunchPad has been shipped, and so I should have it soon.  I figured it'd be good to make some forward progress anyway, so I'm going to go ahead and do this post using my 28-pin TSSOP target board with the F2132, but talk in terms of the G2211 and the LaunchPad.  I'll change any discrepancies as soon as I have a LaunchPad with which to program and take pictures.

This post will describe a little of what you need to use TI's Code Composer Studio.  This programming environment, or Interactive Development Environment (IDE) is based on the open-source project Eclipse.  Eclipse is a great editing environment, and you should find it fairly easy to use for programming your MSP430.  The TI LaunchPad wiki has a link from which you can download the software; it does require registration with TI, but with your account you are also able to request free samples of other products (including MSP430's) to try out.  CCS can be used free of charge, but limits you to 16 kb of code.  While that may not sound like much, keep in mind the MSP430's that come with the LaunchPad have no more than 2 kb of programming space!  Code used to program the MSP430 turns out to be very efficient and dense, and won't take up much space.  We'll be able to see how much space our code takes up when we start using the debugger included with CCS.

Once you've installed CCS, start it up and it will ask for a workspace.  The workspace is just the directory where you will keep your projects; you can always change it later if you need to with the 'Change Workspace' option in the file menu.  For now, use something simple, like ~/My Documents/MSP430 LaunchPad.  Once that's done, you should have a welcome screen come up, that looks like this image.  You can enter the IDE itself by clicking on the cube in the upper right corner; but first, take note of the Getting Started icon.  Clicking on this will bring you to a few links with lots of helpful information on how to use CCS.  I would recommend looking through these before getting started, especially if you've never used an IDE before.

Assuming you've now done that, or are comfortable already with this type of interface, close the welcome screen (you can come back to it with the 'Welcome' option in the help menu) and bring up the interactive editor.  There's not too much here at first, so let's go ahead and start a new project.  Select File → New → CCS Project, and name your project something descriptive.  I like to give the program a name, and include a suffix to specify which MSP430 the program is targeting.  For blinky, I name the project something like blinky_G2211.  Click Next, and make sure that the Project Type is selected as MSP430 (should be the only option if you installed the CCS version with only MSP430 support.)  Click Next.  There's nothing to do on the next page for now, so click Next again.  On the final screen, we need to choose the device we're programming.  Make sure the Output Type is selected as Executable, and then choose the MSP430G2XXX in the filter for the Device Variant.  The filter allows you to select subfamilies of the MSP430 to reduce the number of devices you have to sort through to find yours.  Once you've filtered the results, choose MSP430G2211 for the Device Variant.  For now, the other options should be fine with their default settings.  A quick word before continuing; be sure you choose the correct device variant here; different linkers are needed for different MSP430 devices, so be sure to choose the one that matches your target device.

Click next one last time, and you should see your new project come up in the left-most window.  The project creates a sub-directory in your workspace that holds all the files and information needed for downloading the code into your chip.  But first, we need to make some code to download.  Go to File → New → Source File, and enter a name for the source file that ends with .c; something descriptive is helpful, but for larger projects with multiple source files, something like main.c is a good choice.  Note that CCS will give you a warning until your filename has a .c extension on it.  Go ahead and click Finish, and a new window opens up in which you can type your code.  Go ahead and fill in your code for blinky, and be sure to give it some good comments to explain how it works.  Make sure you have one blank line at the end.  CCS defaults to issuing a warning if there is any text on the last line of the code.  If someone knows how to change this behavior, let me know.  Otherwise, just live with the quirk.

Note that I've changed the size of my windows.  I like to have my editor show 80 columns (a standard for terminal windows) so that I can avoid overly-long lines of code if possible.  Feel free to adjust the window sizes to whatever is useful to you.  Ok, we have code, now we need to compile it.  Technically we don't have to compile before loading it into our MSP430, but I think it's a good idea to get all compile-time bugs sorted out first.  The 'Build Active Project' button to the right of the print button will compile your code for you.  Alternatively, you can select Project → Build Active Project.  If you didn't make any typographical errors, your code should compile without any errors.  The compiler brings up two new windows at the bottom: a Console showing the compiler commands and results, and a Problems list that would show any compiler errors or warnings.  The code given in the previous post should compile error-free.

Alright, now that we're confident our code should work, let's load it into the MSP430!  Plug your LaunchPad into your USB port.  If you've installed the drivers correctly, then click the Debug button (looks like a little beetle) or alternatively select Target → Debug Active Project.  The debugger will change the windows, make sure your code has been compiled since any changes were made, then check to be sure your MSP430 is connected.  If your chip isn't powered properly, it won't detect the device at all.  If everything is powered and installed right, it should just load the code and give you the debugging environment windows.  Note that at the bottom window, it shows you the size of the code loaded into the MSP430.  Blinky (as I wrote it) shows Text: 86 bytes  Data: 2 bytes.  Blinky is by no means a complicated program, but as you can see the size of our programs won't be very high.  the 2 kb that comes with each of your G2211 and G2231 is more than enough for what you are able to do with those chips.

If you were expecting right away to see your LED blinking away merrily, you'll be disappointed.  The debugger actually holds the chip in a state just after a Power Up Reset (abbreviated PUC).  In the middle window, you should see your code with the line at void main(void) { highlighted.  This window shows the position in the code the chip is currently looking.  We'll look at using this feature to our advantage shortly, but for now just click the green 'Run' arrow at the left side of the debug window.  This turns off the debugging control of the clock, and lets the MSP430 run normally.  The LED should be blinking about once a second or so.  If, however, you run your program and the LED stays on, check to make sure you fixed the problem in my original code; if you declare int count; you won't ever count up to 60,000.  You should be declaring unisgned int count; in your code instead.

If after all of this you see your LED blinking, then congratulations, you've just finished your first MSP430 project!  Otherwise, move on to the next tutorial anyway.  If you can't get your code to work, then the debugger may be able to show where the error is occurring.  To leave the debugger, click the 'Terminate All' icon near the 'Run' icon.