Tuesday, August 17, 2010

Half Duplex Software UART on the LaunchPad

Before I get into this post, I want to let you all know that the very basic oscilloscope project is coming; this post is the first in a series which will lead up to the final project. Before you all get too excited though, the scope will be very limited because of the low sample rate we must have. Be prepared to see some cool mini-projects as we work toward our main goal. This blog and the ones which follow, mirror what I have done with the F5528 for my own personal project.

This post is fairly short; this is due to the fact that I will break down the larger project into smaller posts to keep things bite sized and allow you to follow my design process. I think it is very important to learn how to develop in steps when working with a complex design; there are many benefits to doing things this way.

A Part of the Big Picture

Making a software UART which can receive was a clear first step in making sure we can get an ADC to work. In order to see what we are getting with the ADC we need a computer interface, and in order to control the LaunchPad we needed to be able to receive data. In addition to using this in our oscilloscope project, there has been a lot of interest in the community for a software UART which can receive.

Before we go onto looking at the code, I want to discuss the limitations of this specific software UART. I have not tested the overall throughput to see how fast it can go, as such, there will be a lower limit on the bit times regardless of clock speed. Clock speed can be used though to make the whole system run faster. Before we finish the scope project we will be running at 8 or 16 MHz, and sending data over an FTDI chip much faster than the LaunchPads debugging UART allows. For now though I want to keep the baby steps to something everyone can do (with or without the FTDI chip).

Another major limitation of this code is that it can not receiving while sending, and it can not send while receiving. It IS possible to write a software UART which is full duplex, though I will not be designing one; at least for the foreseeable future.

The Code

The code is posted on github at http://gist.github.com/532047 for those of you who have trouble seeing the embedded code here. I just love github, I do not know what I would do without it.


A Quick Explanation of the Code

The code is decently documented, and you all should be familiar with the transmit part of the code; if you aren't, please see this past post where I go over the transmit functionality. I will not really go into detail on all the specific lines of code but I will discuss how the receive code works.

For every byte that is sent over UART there is a start bit which always moves the signal from high to low. Our code recognizes this by throwing an interrupt on the RXD pin when a signal goes from high to low. It is important to disable this once the receive sequence is started, and it is also just as important to re-enable the interrupt once we are done receiving a byte. Once the interrupt is thrown, the timer and other values are initialized.

Next, the timer interrupt cycles through each bit in a very similar way the transmit function does. The major difference between the two is that instead of shifting the bits out, it reads the RXD pin and sets a bit in the RXByte. This is a bit hard to understand if you have not seen this method being used before. The current bit being read will set or leave cleared the 13th bit in RXByte; the entire byte is then immediately shifted once in order to slowly move the bits into the correct location. After an entire sequence is done all the bits will end up in the correct location.

Finally the stop bit is read, and the timer finishes up. It not only stops the timer and re-enable the interrupt on the RXD pin so we can receive another byte, but it also makes sure the start and stop bits are correct values. If an incorrect value has been received for these bits, the received value is ignored.

The final tricky part of this code, is understanding how the main loop knows a value has been received and how the low power modes work. It wouldn't be an MSP430 project if there wasn't some form of power saving going on :-P.

The main loop will go to sleep every iteration unless there is a value which has just been received, in which case the loop will run again. In the timer code, if the received byte is validated and shown to have no errors, it not only sets the hasReceived flag but also forces the CPU to leave the low power mode, which lets the main loop run and react to the received value.

Conclusions

As always, I hope that this code is something that helps with your projects and is peaks your interest in what is to come.

On a separate note, I am very happy to see the community growing. I have had an increase in viewers and I see more activity on the 43oh forums. I check these forums every few days and do my best to answer any questions, so if you have not joined yet I highly recommend doing so. I also plan on taking a more in depth look at the LaunchPad wiki Learning Community that a TI employee started up a bit ago. There seems to be a good amount of information already present on the site, and there also seems to be a huge potential for growth. I really am grateful to TI for providing us all with support and a large number of resources to get the community going.

So, comment away. Your comments are the fuel which my creative juices run on :-P

IMPORTANT EDIT: There is a small error in the code I presented above. The transmit function is problematic because if you send two bytes in a row the TXByte value would be changed before it is done being transmitted. For now I will write in a quick fix, in the next post I will provide a slightly more efficient solution. The code is updated above.

62 comments:

  1. I may have missed it, but why does the oscilloscope need to be able to receive data?

    my idea of the oscilloscope was just to send data to the PC and use a program to sort the values, and use buttons, with interrupts to change certain values, settings.

    ReplyDelete
  2. Justin,

    Your idea is completely valid and probably easier to implement than using a PC to control the oscilloscope, in addition to displaying the values it reads. The reason I chose to do it this way is so that we have more flexibility and so that no external components are needed.

    It really just comes down to personal preference. I would rather control the device with a button click on a computer program, instead of going back and forth between a computer program and hardware buttons. Also this allows us to have more control in the long term; we can have much more complex parameters than a few push buttons would allow.

    I do plan on providing an executable with the project for those who do not want to write their own computer applications.

    ReplyDelete
  3. I'm watching this series with interest. Only since getting my LaunchPad do I now understand the benefit of an oscilloscope to the hobbyist market!

    Ultimately, I'd love a completely standalone unit, with it's own LCD rather than a PC driven device. But I have no idea what limitations this would impose aside from the limited flash storage which would have to include graphical functions.

    ReplyDelete
  4. I see, Your right about the settings, as for the LCD you driven O-scope, I was thinking of picking up one of these
    http://www.sparkfun.com/commerce/product_info.php?products_id=9484
    or it can give some good ideas about how to use an LCD with the O-scope

    keep up the good work.

    ReplyDelete
  5. Great code!! I was kind of waiting something like this...I'm busy right now with school but I will try to use this code and to see if i can understand it as soon as I have some time.

    ReplyDelete
  6. Please follow my and spread the word of my new blog:

    http://practical-embedded-hacks.blogspot.com/

    ReplyDelete
  7. First, Tabish, this it not the place to be advertising your blog, I'm sorry. I will not delete the post, but please go to all the forums and post there instead. I am happy to support a fellow blog in the community, but I would like to keep my comment section free of advertisements.

    @Gareth
    Building a standalone oscilloscope can be quite daunting. There is so much that needs to go into it in order to make it useful; precisely controlling a graphic screen is hard to do with a microcomputer. To do this with a microcomputer you would need to seriously reduce your sampling rate to the point where it is not useful. If you are really interested though in making a standalone unit, look into FPGA's. I can help you get started if you want; but be warned, FPGA's are really intense.

    @Justin and Gareth
    I have heard good things about that LCD, but never used one. It could be great for a small project. Both of you, feel free to build a scope with it! Don't let me previous comment hold you back; just know that it will be very hard and very limited in functionality.

    @Everyone
    Thank you for all the comments.

    ReplyDelete
  8. Nice work on the Half Duplex Uart NJC.
    Works perfect, I tried pushing it higher using standard baud rates but no go yet, I did not trace the code to see where it was hanging up.
    Thanks for the code, keep it up

    ReplyDelete
  9. Megachip,

    Thank you. You reminded me, there is a problem with the code I should fix in this post. I was going to mention it in the next post, but I should update this one too. In the transmit function we need to either put the while loop at the end, so we do not modify TXByte as it is sending, or put TXByte into a temporary variable. The latter would allow for faster data throughput.

    Hope that works for you.

    ReplyDelete
  10. Hey NJC,
    I wanted to note that with the update to the code you can set your terminal to any Baud above 9600 and it works fine. (you can not change the virtual port speed). The speed does not change as far as I can tell but it syncs just fine.
    I would like to hear your comments on that because I do not know the answer.
    Thanks my C++ Guru !!!

    ReplyDelete
  11. Megachip,

    I am not sure I understand your question. I am confused since you mention that you verified the software UART at faster speeds than 9600 baud? It seems as if you are still using the LaunchPad's UART interface to test this? It is not possible for the LaunchPad to work faster than 9600 (at least, thats what the documentation says).

    I am in no way an expert in VCPs, but I do know that when using the 5528, one does not need to set a baud rate on the VCP at all. If one does set the baud rate it does not matter since it has no effect on the speed at which the device communicates. This is different though for the FTDI chips, which use the baud rate set in the VCP.

    What hardware are you using to test this? To be honest I have not tested the upper limits of this code yet, and might not get around to checking it anytime soon. Thanks though for testing the code! Maybe your findings can help me make a better version. Once I know more about your setup I might be able to provide a better answer to your question.

    Looking forward to your response. :-) Thanks for the comments

    ReplyDelete
  12. I am using the LaunchPads UART, Your Half Duplex software ,RealTerm and Hyperterm.
    I did not find any magic here, I was just asking a question about terminals and BAUD rate settings. I was confused because we set a baud rate and I expected the terminal to only work at that baud.

    Both the Uart programs act the same and I did not realize it till now.

    It is ONLY THE SOFTWARE UART , NOT THE VCP.

    You can run your terminal baud at any rate above 9600 and it will work but the speed does not change. We are still only going as fast as the VCP can go.

    What I do not understand is how the VCP is set to 9600 and our program is set to 9600 yet the terminal works at any given speed 9600 and above. Maybe this is the nature of a Software UART and I have only worked with Hardware UARTS.

    I hope that answers your questions.

    ReplyDelete
  13. @Megachip: It sounds like the terminal programs are just compensating somehow.

    @NJC: I really like the new header. Did you take the photos, or find them on TI's site?

    -Doc

    ReplyDelete
  14. @Megachip
    From my experience I think doc is right. I think that the weird behavior is related to what I said in my last post. The LaunchPad might not use the baud rate set in the terminal and determine the baud rate automatically. USB communication does not need a baud rate because of how it works. Sorry I can't provide a better answer, I am no expert on the USB protocol.

    @Doc
    Thank you. :-) I took the photo myself, with my phone. I was going to re-do it with a nicer camera, but never got around to it. I should probably fix the image up a bit. I spent an hour or so making it last weekend since I've been without internet (except at work). That is why it has taken me a while to write up my next post, still no internet at home.

    ReplyDelete
  15. Thanks for the UART code. I've used it in my RPN Calculator and my SPI Explorer programs for Launchpad.

    I made changes so that I have getc() and putc(). The code is at:

    http://blog.hodgepig.org/articles/000047-rpn/index.html

    http://blog.hodgepig.org/articles/000048-spi/index.html

    ReplyDelete
  16. Hi NJC et al. !

    I got inspiration from your great code, but I'm facing the following issue :

    My current launchpad app has to reply to some commands sent by a C++ client application. But when several chars are sent "in a row" by my client app, the Launchpad hasn't time enough to check the command (basically with strcmp) and reply if required.

    I guess I can increase the master clock to allow more instructions to be executed once a char has been received (and modify Bit_time and Bit_time_5 accordingly), but how to do that, while keeping the 9600 baud timing with accuracy ?

    ReplyDelete
  17. Efcis,

    If your commands have a known maximum character length which is not too large, you could make a buffer for the incoming values which would allow you to have more time to analyse them, unless you are constantly sending commands. Another option is to change the C++ app if you can, and make the commands smaller.

    Changing the clock might do the trick, depending on how large the string commands are. See the comment below to make sure the baud rate is set correctly.

    // 9600 Baud, SMCLK=1MHz (1MHz/9600)=104

    Also note that this code can not transmit anything while it is receiving. Hope that answers your questions.

    ReplyDelete
  18. NCJ,

    Thanks for your reply. I already buffer the received characters, but it looks like this process (buffering and checking if the last received char is a CR) take too much time to allow the next char to be received. The only way is to add a delay between two consecutive sent chars (1 ms) in the client, that doesn't satisfy me.

    I'm also facing something strange : If I use a SMCLOCK / 2 clock for the timer to decrease the rate to 4800 bauds (to allow more CPU time between two chars), it doesn't work.

    I'm doing a simple

    TACTL = TASSEL_2 + MC_2 + ID_1;

    in the Port_1 interrupt (and in transmit), but it looks like the timings are incorrect ! As I don't own any oscilloscope / DSO, it's hard to figure what's happening exactly.

    Any idea ?

    ReplyDelete
  19. Hey efcis,
    Would you mind making a post on the 43oh.com/forum forums on this topic? I'll be able to answer you more in depth there, in addition to there being more people there who can help.

    ReplyDelete
  20. Hey NJC,

    Nice post/code. Thanks a lot for it.

    A question. Is there a way to still use the P1.1 and P1.2 for other purposes (push-button for instance)?
    Can I poll for button changes in the long-pooling while after interrupts are enabled and before transmission occurs?

    ReplyDelete
  21. I have successfully run the transmit code from http://www.msp430launchpad.com/2010/07/launchpads-example-project-ripped-open.html When I try to run this UART code, I expected that after I sent a character from RealTerm it would be echoed back to RealTerm. This did not happen. I inserted code to toggle the green LED after line # 143 hasReceived = true; This worked as expected. I then inserted code to toggle the red LED when the main while(1) loop is entered. The LED lights up when the program is initially run, but never toggles again.
    I appears that the code never returns to the while(1) loop and therefore never Transmit()'s. Any suggestions?
    Hardware:Windows Vista Home Premium 64 SP2 4 gig RAM. LaunchPad Rev 1.4 MSP430G2231 all original, all jumpers left as received.
    Thanks,
    Gertrude

    ReplyDelete
  22. @Fábio - You cannot use the pins that are used for the software UART for anything but UART while the software UART is running unless you do some tricky enabling and disabling of the software UART in your program.

    @Gertrude - Have you double checked that the code is the same as my example and double checked all of the wires and connectors? If all else fails and you have a logic analyzer, test the signal to ensure that the baud rate is working correctly.

    ReplyDelete
  23. Great post, i have been banging my head against anything i can find to understand the following line of code.

    TXByte = TXByte >> 1;

    Where do the bits get shifted to? On to the P1.1 pin? ( which is connected to the PC?)

    Please save my head

    ReplyDelete
  24. Venu, good question, I know this can be hard for people new to embedded programming. You can think of the >> operator like any other mathematical operator, such as + or -. So when you do y = x + 1; y is not equal to x + 1. When you do x = x + 1; x is now equal to itself plus one. So when you do y = x >> 1; y is equal to x shifted to the right once. The lowest bit just disappears (there is another shift in assembly that causes it to go to the highest big, but not in this case).

    So for the example in my code, the new TXByte is now equal to itself shifted one bit to the right. 0b0010 now equals 0b0001.

    Hope that saved your head!

    ReplyDelete
  25. Awesome post NJC, I received my Launchpads last week and currently working on a PC USB > RGB LED controller with the launchpad, definitely going to be using some of this code if you dont mind :)

    For those of you without scopes, I have version 1 of the following: http://www.seeedstudio.com/depot/dso-nano-v2-p-681.html?cPath=174&zenid=a4454af982f08f8739827a0b629323e6
    and I must say I highly recommend it as a beginners/hobbyist scope. Its really not that expensive and it will save you alot of headaches to just go ahead and grab one ;) (when they are in stock again...)

    ReplyDelete
  26. Hello NJC, first of all I'd like to say thanks for posting this code, it got me on the right track with my own UART.

    There's something I wish to point out though on the receiving part, as it has given me quite some headaches because it wasn't working properly and randomly skipping bit 0 or bit 1 (were read as 0 when they should've been 1) from the byte it was supposed to receive.

    In the Port1 ISR, instead of
    CCR0 = TAR;
    CCR0 += Bit_time_5;
    I used
    CCR0 = TAR + Bit_time_5;
    and the bit skipping problem was solved. I still can't quite figure out why this was happening as the CCR0 interrupt shouldn't trigger, because it's obviously disabled, but something was definitely not working properly.

    ReplyDelete
  27. @Rob - use the code all you want! Thats what its there for :-) just put a little blurb in somewhere that points back to my blog.

    @Bloodred - interesting find. It could be that you are missing a bit just because of the time the MCU takes to process the Port1 ISR. If you lowered the bit time and half bit time I'm guessing the problem would go away.

    ReplyDelete
  28. Will of course give credit where credit is due :)

    Question: I'm trying to run at speeds faster than 1MHz, such as 4, 8 or even 16MHz to get smoother software pwm.. but this cause's issues with the UART timing since the 1MHz value is reasonably calibrated on the device but trying to run at expected faster speeds gives unpredictable results... have you found a way around this? or just experiment with the bit_time variable via trial and error?
    sorry if there is an answer to this but I'm unable to Google as I have 9Mb of internet left until tomorrow... The joys of Africa... lol.

    ReplyDelete
  29. @NJC
    I don't think it was a timing issue, the change I made shouldn't make much of a difference if any at all. Quite curious, I still can't figure out the reason. I've been using that code in my project extensively and it has been working perfectly, form what I can tell it never misinterprets a received value.

    Wouldn't halving bit time effectively double baud rate? I don't need anything faster, 9600 is plenty as my project only has to receive about 80bps tops.

    ReplyDelete
  30. @Rob - I actually never ran into trouble with that since I do not extensively use the G2231, I would sooner use the F2013 (which had calibration constants for most frequencies). I would recommend using whatever tools you have to measure the clock frequency of your MSP430 and then recalculate the bit_time based off of that.

    @Bloodred - very interesting. Have you tried hooking up a scope or logic analyzer to the pins (if you have one)? I really am not sure what could be causing that weird behavior. And yes, halving the bit time would effectively double the baud rate, but you also have to make sure to half the bit_time_5 also.

    ReplyDelete
  31. Three comments about the RX part:
    1. It's better to set the compare value immediately when the pin interrupt is run for more consistent timing.
    2. It seems that the start bit detection is immanent to the pin interrupt and thus the first timer interrupt is supposed to happen in the middle of bit 0 (first data bit to be received). Which means that the compare value should be greater than half a bit time..
    3. Consecutive bytes are missed regardless of processor speed because the timer interrupt is used once more just to check the received data.
    The check can happen immediately after shifting in the last bit, so the "if ( BitCnt == 0)" block should come after the shifting part (removed from else block)..
    I hope my observations are correct and useful to folks wanting to implement a FIFO.. Happy hacking!
    Thanks for sharing.

    ReplyDelete
  32. RE: April 27, 2011 3:16 PM
    In addition to the above, timing is much less critical if you boost up to e.g. 8 MHz using the DCO. For the async serial it needs calibration which can be done automatically using the included 32 kHz watch crystal and the example code from slac463a.zip - msp430x20xx_dco_flashcal.c.
    The timer clock or bit_times need to be adjusted, and the compare value set from the pin interrupt needs to be set to 1.5 bit times.

    ReplyDelete
  33. Excellent post - this code worked perfectly for me, and with only slight modification I've been able to get it to suit my purposes for debugging another tricky project I'm working on with my G2252.

    My question, though - you say this is a "Software" UART, and I don't see anything in this code that looks like it's calling upon the MSP430's hardware USCI module (which I understand contains UART support, but I confess that that part of the documentation has mostly lost me).

    So am I correct in my understanding that this code is just bit-banging serial communication using GPIOs, or is there some aspect of the MSP's USCI/UART hardware that's being leveraged here?

    If the former is the case, are there some advantages or disadvantages to doing it this way vs. implementing the "hardware" UART (whatever this would mean)?

    ReplyDelete
  34. Could you please redo this code into SINGLE reusable and standalone function? (so there will be nothing in main() except:

    magic_function("uart string to send");

    Pleaase

    ReplyDelete
  35. @lolez I did this for my Launchpad SPI Explorer.
    http://blog.hodgepig.org/2010/09/10/575/

    See uart.c in http://blog.hodgepig.org/wp-uploads/articles/000048-spi/spi.tar.gz

    ReplyDelete
  36. it's work very good

    tks Nicholas

    Ed

    ReplyDelete
  37. Nicholas in your code you noted :
    // 9600 Baud, SMCLK=1MHz (1MHz/9600)=104

    But when I try to change the value by 26 this value for 38400 bauds communication it doesn't work.

    Why ?

    ReplyDelete
  38. It might be time for me to update this post and make the functions a bit more reliable. I do admit that the code presented here is not perfect.

    If you do need a device with a flawless UART, I recommend using one of the newer value line chips that have a hardware UART built in.

    @Eddy B - It should work just fine as long as you are not using the LaunchPad's built in application UART to communicate with the PC. The LaunchPad's UART supports a maximum of 9600 baud. I recommend using an FTDI chip if you are having trouble communicating at higher speeds.

    ReplyDelete
  39. "If you do need a device with a flawless UART, I recommend using one of the newer value line chips that have a hardware UART built in."

    The documentation is a little confusing in this regard - it seems to indicate that all of the value line devices have an SPI/I2C UART - does this not also mean there's an async serial UART? Which devices do have this feature?

    ReplyDelete
  40. @Andrew - The MSP430 contains either the USI and/or the USCI. You have to look closely at the documentation to see what each individual chip supports. For example, the MSP430G2231 only has a USI and supports just I2C and SPI. On the other hand, the MSP430G2153 has two USCIs and supports UART, SPI, I2C, and IrDA.

    ReplyDelete
  41. @NJC - Thanks, this makes sense to me.

    The code in this post, as I understand it, is a way to fake a UART on an MSP that doesn't support it in hardware, rather than a method for interfacing with real UART hardware, correct?

    To say it differently, it would be inefficient to implement the above method for serial communication on an MSP430G2153, correct?

    ReplyDelete
  42. Amazing Stuff!

    Within 45 minutes, I was switching LED's on and off, only when I pressed the spacebar (through the terminal!)

    Thank you Nicholas - I have a $5 Donation on it's way -- enough to buy a pint of beer?

    ReplyDelete
  43. @Andrew - Yes, it is a way to fake a UART that doesn't have a hardware UART. Redundant and inferior would be a better way to describe it than inefficient.

    @Tendolla - Thank you so much! It might actually be enough for a pitcher of beer. :-) Glad I could help you get started with the LaunchPad. Thanks again!

    ReplyDelete
  44. hi everybody,

    i try to change TDX pin to different fron P 1.1 and P 1.2 but only works on P 1.5 however i also need other pins as TDX. Any one can solve this problem or can give advise to solve the problem???

    Thanks.
    Best Regarts,
    Burak.

    ReplyDelete
  45. @Burak,

    Which other pins are you trying to use? You'll want to make sure you have the jumper pulled off to disable the button for P1.3 - I believe that pin gets pulled high by an onboard resistor when the switch is enabled.

    Likewise, the LEDs at 1.0 and 1.6 may be interfering.

    ReplyDelete
  46. This comment has been removed by the author.

    ReplyDelete
  47. HI

    Great post NJC.

    I used this code for my project(MCU msp430g2553 having one hard uart)
    where MCU msp430g2553 is working as a middle buffer between other two device. as shown


    Device1---------- MY MCU-------- Device2
    Hard uart Hard uart||soft Uart Hard uart

    and also n full duplex mode (so i dedicate another timer for transmit)

    for single digit transmit and receive is working fine. but on continue communication some char (or say bit) get corrupted or missed some time. i used circular buffer in between to make communication more reliable thing get improved from it but not 100%.

    please suggest some solution.

    ReplyDelete
  48. Hi,

    thanks a lot for the code man :)

    i use it for led display via Serial and it work like a charm.

    i wanted to implement a new functionality but it require the loop in main function to go on without waiting for a Serial transmition.

    I'm presently crushing my head to the wall because each try result in the fact that serial won't work anymore :(

    need help on that

    Thanks

    ReplyDelete
  49. Anonymous,

    Instead of implementing a continuous loop for the new function you're writing, try setting it up as a function that gets called at a periodic basis as an interrupt by the timer (in much the same way that this serial code works).
    If you're not using the WDT (Watchdog timer), it can be used as an additional periodic timer, calling your function regularly.

    ReplyDelete
  50. nice code. Thank you!

    But i'm still confused. Why do you need two definitions of Bittime(#define Bit_time 104 // 9600 Baud, SMCLK=1MHz (1MHz/9600)=104
    #define Bit_time_5 52 // Time for half a bit).
    And in the #pragma vector=PORT1_VECTOR function you set the timer till first bit with "Bit_time_5". Can you explain this for me? Thanks!

    ReplyDelete
  51. @zhenyu - The reason we have a half bit time, is so that we can start measuring the received signal one half bit time after the initial transition from high to low. Sure, the half bit time could be calculated every time we need it, but I just store it from the beginning to make the function a bit more efficient.

    Does that make sense?

    ReplyDelete
  52. First off, thanks for the great site! It's helped a lot so far.

    I have a problem using your code with my launchpad. My device is a G2553.

    When I send characters to it, it sends back a character that you would usually expect when the baud rate is off. But I've tried all the possible baud rates as well as changing the bit-rates in the code. Nothing works.

    Any ideas?

    ReplyDelete
  53. What particular character is it sending back? If it's not printable ASCII, could you give us the hex?

    ReplyDelete
  54. Hello,

    First thank you for these posts, very helpful. I am writing code in c that needs to send an email after I have sent a particular hex message via UART to the computer. I have everything I need, but I am having trouble setting the necessary flag after the signal is received. Can you offer any advice on how to accomplish this? Is it even possible? If not is there a way to do this with seperate c modules.

    PS: I have verified each piece of code, just need help combining them.

    ReplyDelete
    Replies
    1. Let me clarify,
      I want the launchpad to send a signal that tells the computer to send an email. I have code for sending emails, and thanks to you the uart. I want an email sent after the uart comm has taken place.
      Thanks

      Delete
    2. I would recommend getting everything to work in steps. First make a C program which can receive characters received via the LauchPad's UART and then display them. There are many examples online for serial communication in C. If you run into any additional trouble, try the 43oh.com/forums. Hope that helps!

      Delete
    3. @njc

      All the code is great but I keep running into errors on the CCR0 += Bit_Time; I get the "expected an expression" error... Any ideas why that is(I'm using the MSP430G2553)??

      Delete
    4. Are you using CCS? If so, I'm not quite sure why that is happening. You might want to create a post on TI's forums.

      http://e2e.ti.com/support/microcontrollers/msp430/default.aspx

      Sorry I could not be of more help. Best of luck!

      Delete
  55. Hello NJC,

    thank you again for this awesome code. I have been using it for simple communication for a while, even extending it to parse fixed string lengths (e.g. 3 bytes, then decode to make sense of it).

    I have found an interesting result in my code, I was wondering if you'd have any insight as "where to go look first!"

    If I use realterm to send 3 separate hex values (e.g. 0xB1 0x04 0x7F) my code responds, parses and writes a value back. lovely. But the second I set it up to stream the 3 hex values one after the other, everything falls apart. The '430 misses something and i get errors in the parsing.

    Any ideas?

    ReplyDelete
    Replies
    1. Thank you for the question. The first thing that comes to mind, is that you might be stuck in an interrupt, not allowing more bytes to come in. Do you parse the data in an interrupt? Or in your main loop?

      It is almost always a bad idea to do processing in an interrupt. Ideally, you should wake up the MCU and set a flag showing an event occurred. If you are stuck in an interrupt processing the data when more bytes come in, you will miss the new bytes.

      I hope that helps.

      Delete
  56. Hey NJC,
    Great post of code. Thanks a lot for it.
    I am student and i am doing my project, I try to communicate between msp430g2553 and radio module via two pins of UART(TX, RX), basically is chip to chip communication. Does this code support for msp430G2553 as well.
    Thank you so much. Your reply will be really helpful to me.

    ReplyDelete
    Replies
    1. Yvonne, thank you for commenting! The MSP430G2553 has a hardware UART, so you actually do not need to use this code (which provides a software UART when a hardware UART does not exist). To actually answer your question, this code should run on (with minor modifications to the timer code) on any MSP430. If you run into any more trouble, I recommend the 430oh forums or the TI e2e forums. Best of luck!

      Delete

Note: Only a member of this blog may post a comment.