Jump to content
43oh

State Machine Example for MSP430F5529


Recommended Posts

Ages ago, I attempted to describe my experience creating a state machine for the MSP430. I never did finish that mission. This post is me crossing that finish line!

 

 

Today, I ported my code over to the MSP430F5529, split up the one source code file into several files and tested it with the MSP-EXP430F5529LP launchpad board. I am using Code Composer V6. 

 

Here's a Quick Start guide on using this project:

1. Create a new F5529 target project,

2. Import these files into that project and

3. Compile it.

4. Hook up your F5529 Launchpad to your PC

5. Press F11 to run the code

6. Press the Start Triangle

7. Press and hold S1

8. The state machine will run through everything in about 13 seconds.

 

Process Description:

1. The green LED to light up for three seconds then shut off.

2. The red LED will light up immediately when green shuts off.

3. The red LED will stay lit for about 10 seconds then shut off.

4. The green LED will then light up until you let go of S1 button.

 

This code has been adapted from a project that I did for a client three years ago. The project was a battery charger that had to charge batteries for 12 hours maximum and then shut off. They didn't want the batteries to be over charged.

 

The embedded hardware could sense when the batteries where connected (docked) to the charger (S1 == docked signal) and that was the START trigger event. The timer state machine would then take over and push the charger state machine through its paces.

 

There are two state machines in the code:

- Charger State Machine states: OFF, STARTING, RUNNING, COMPLETE

- Timer State Machine states: STOPPED, TICKING, RESET

 

The period of the timer state machine is controlled by variables in the RE_defines.h file. The code comments there should be enough to start your learning curve on setting up a TimerA peripheral. 

 

Notes:

1. I have attached a zip file because there are eight source code files in this project.  

2. The zip file was created by exporting it from CCS6 so it contains all the CCS6 configuration files.

3. You may be able to just import the entire project rather than create a new one. 

 

 

Releasing this code is a difficult decision because this code is money to me. It has put food in the mouths of my family. By releasing this code into the wild, I am investing in you. You are worth it!  

 

I want you to succeed so I have put a liberal MIT license on this code. When you use it then please credit me. My contact details are in the code.

 

 

Please show me what you make with it!

 

 

ChargerStateMachine.zip

Link to post
Share on other sites

I'm glad to see you're using enums and not #defines for state values.

What's novel here though?

Your state machine just uses the popular switch() statement example onto which all neophyte programmers have latched.

 

The whole reason for using the switch statement is that the C standards committee removed the freedom afforded to assembler programmers: the freedom to write variables to the program counter.

In removing this freedom, the committee has forced C compliant embedded developers to bloat their code size with a jump table or worse, if statements if the value handled by the switch is not sequential.

If you wanted to show something more novel (but old really), use labels as values:

 

https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html

 

Now instead of creating a separate enum, copying those enums into a switch statement and maintaining the correspondence of those two as you develop, you simply create labels in your code and put a single goto at the beginning of your function.

Your state variable becomes a const void* pointer instead.

If your state machine is uninitialized, your pointer should be NULL.

When you want to save the state, just copy the label value into the pointer.

Replace your switch with a goto and you are good to go.

 

Faster at execution time, no bloating jump table and only costs an extra byte of ram over a single byte state variable.

 

And what's that, how are external pieces of code supposed to know what state you're in???

State is only a summary of the context of your state machine; that is it reflects an accumulation of your past inputs.

So if you have no other variables in your state machine changing according to these inputs, why would you need to maintain state?

(apologies for the rhetorical questions).

 

And yes, this is not ANSCI C, so it's not as portable as switch.

Unless people start using it though it will never be adopted.

Link to post
Share on other sites

Also a great way to implement a complex state machine, but some points:

 

1) You still maintain a declaration list and a definition list of these functions (unless you combine in the header)

2) Member functions which are not states but have the same signature as state methods could still be assigned to the member function pointer without the compiler catching it. (not that a const void* pointer is any better in this respect, just saying)

3) Plain old C function pointers are more portable yet, and work without class instantiations

4) Functional dispatch requires another stack frame

5) The requirement of partitioning each state into its own function creates a lot of boilerplate.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...