Jump to content
43oh

Yet another UART issue. :)


Recommended Posts

Hi,

 

 
New MSP430 LP user. Hope Im posting in the right forum part.
 
I found out using the combination MSP430G2553, Launchpad 1.5 (jumpers in hw) + Linux + UART is a bit of a problem.
It seems there's always problems with UART communication.
 
I confirmed http://forum.43oh.com/topic/1643-g2553-hardware-uart-hello-world-example/ to work perfectly so this is why I can't understand what's
wrong with my code.
 
Here's my code
 

 

.include "msp430g2553.inc"

RXD     equ     0x02
TXD     equ     0x04

.org 0xc000

start:
  dint
  mov.w #(WDTPW|WDTHOLD), &WDTCTL
  mov.w #0x0280, SP

; CPU 1MHz

  mov.w #CALBC1_1MHZ, &BCSCTL1 ; 1MHz
  mov.w #CALDCO_1MHZ, &DCOCTL ; 1MHz

  mov.b #(RXD+TXD), &P1SEL
  mov.b #(RXD+TXD), &P1SEL2

  bis.b #UCSSEL_2|UCSWRST, &UCA0CTL1
  mov.b #0x68, &UCA0BR0
  mov.b #0, &UCA0BR1
  bis.b #UCBRS0, &UCA0MCTL
  bic.b #UCSWRST, &UCA0CTL1
  eint

main:
  bit.b #UCA0TXIFG, &IFG2
  jnz main
  mov.b #'0', &UCA0TXBUF
  jmp main

.org 0xfffe
  dw start

 

 

I can't see why this wouldn't work.

One issue I notice is that my PC pretty much gets unresponsive for 5 sec and then I get I/O error while this doesn't happen with the other

code I confirmed working. I believe this is related to UCSWRST-part.

 

Now, the code above is w/o other stuff within the code. My code might be slightly different but overall the essential parts are still there.

 

The idea is to run the MCU in 1MHz and transfer data in 9600 baud. I just send a 0 to the port for now.

 

If anyone can see anything obvious my eyes can't - please assist :)

 

Regards,

Anders

Link to post
Share on other sites

The only reliable method I've found to wait until something is transmitted is

main_loop:
bit.b #UCA0STAT, &UCBUSY
jz main_loop

That guarentees that it's not transmitting before you transmit. Although TI seems to extensively abuse the IFG flags DON'T use it for serial comm (of ANY KIND) that is NOT what it's intended for. The UCBUSY flag IS intended to indicate when serial com is occuring. So use that instead. I had to fix TI's code several times if I changed the processor frequency because of the use of the IFG flag, (in summary). Use UCBUSY it is specifically their just for what you are doing.

 

You may also want to change a

mov.w #0x0068, &UCA0BR

 

2 stage loading of UCABR0/UCABR1, I use the 16 bit load all the time. Apart from being shorter and using less memory, it's also more obvious what you are doing.

It's not necessary however (LOL).

 

Last but not least UCA0CTL1 probably should be more like

mov.b #UCSSEL_2|UCSWRST, UCA0CTL1

As this clearly configures the register, ORing it with random bits after reset has always lead to trouble for me.

 

You probably should read carefully the baud rate information also. I can't tell you if the number you choose is right off hand (just in case).

 

I hope this helps. If I missed something I'm sure someone else will point it out.

 

Cyb

Link to post
Share on other sites

One issue I notice is that my PC pretty much gets unresponsive for 5 sec and then I get I/O error while this doesn't happen with the other

 

code I confirmed working. I believe this is related to UCSWRST-part.

 

Several platforms that use a TIUSB device to provide serial port emulation, including the MSP430 LaunchPad and the EXP430FR5739, must not transmit any data while a driver is initializing, especially on Linux systems.  If data is received during this period you get the behavior you describe.  On the Linux system you can tell when the driver's ready because /dev/acm? will change from mode 600 to mode 666 allowing user-level access.

 

In BSP430 I have initialization code that spins while displaying an LED pattern until a jumper is removed from the board, indicating that the serial port is ready for use.  At that point the application is released to do whatever it needs to do including serial output.  This only needs to be done when the board is first plugged in (or if power is removed from and restored to the USB circuitry); once the driver is stable you can leave the jumper off and reprogram and restart the application without any problems.  If you're dextrous you can get same effect by holding down the reset button while you plug in the board and wait for the driver to become ready.

 

Somewhere on the forum there's another topic about Linux and serial where this workaround was discovered.

Link to post
Share on other sites

Hi guys, thank you for quick reply.

 

The only reliable method I've found to wait until something is transmitted is

main_loop:
bit.b #UCA0STAT, &UCBUSY
jz main_loop

That guarentees that it's not transmitting before you transmit. Although TI seems to extensively abuse the IFG flags DON'T use it for serial comm (of ANY KIND) that is NOT what it's intended for. The UCBUSY flag IS intended to indicate when serial com is occuring. So use that instead. I had to fix TI's code several times if I changed the processor frequency because of the use of the IFG flag, (in summary). Use UCBUSY it is specifically their just for what you are doing.

 

You may also want to change a

mov.w #0x0068, &UCA0BR

 

2 stage loading of UCABR0/UCABR1, I use the 16 bit load all the time. Apart from being shorter and using less memory, it's also more obvious what you are doing.

It's not necessary however (LOL).

 

Last but not least UCA0CTL1 probably should be more like

mov.b #UCSSEL_2|UCSWRST, UCA0CTL1

As this clearly configures the register, ORing it with random bits after reset has always lead to trouble for me.

 

You probably should read carefully the baud rate information also. I can't tell you if the number you choose is right off hand (just in case).

 

I hope this helps. If I missed something I'm sure someone else will point it out.

 

Cyb

 

Hi,

I altered by using either IFG or UCBUSY. After your recommendation I stick to UCBUSY. I changed the other parts of the code of how you recommended but the issue remains.

The mentioned C-code stated in the beginning works flawlessly. If I load this code first, I can successfully run my own code if I don't reinsert the board.

 

Several platforms that use a TIUSB device to provide serial port emulation, including the MSP430 LaunchPad and the EXP430FR5739, must not transmit any data while a driver is initializing, especially on Linux systems.  If data is received during this period you get the behavior you describe.  On the Linux system you can tell when the driver's ready because /dev/acm? will change from mode 600 to mode 666 allowing user-level access.

 

In BSP430 I have initialization code that spins while displaying an LED pattern until a jumper is removed from the board, indicating that the serial port is ready for use.  At that point the application is released to do whatever it needs to do including serial output.  This only needs to be done when the board is first plugged in (or if power is removed from and restored to the USB circuitry); once the driver is stable you can leave the jumper off and reprogram and restart the application without any problems.  If you're dextrous you can get same effect by holding down the reset button while you plug in the board and wait for the driver to become ready.

 

Somewhere on the forum there's another topic about Linux and serial where this workaround was discovered.

 

Like stated in in this post above, it works flawlessly with the code in my first post (the link) in Linux and if I do exactly the same steps to read the serial port but with my code - it get stuck as you mentioned.

I checked the status of the device and as you said, it stays in 600 until driver is ready.

 

If I load the C-code first I get output. Then I can load mine and I also get output, but baud blarf so maybe there's something wrong in my parameters. I will try and figure that out.

But the issue doesn't describe why his code works but not mine - not consistant behavor on my PC.

 

TY for letting me know more detailed about the issue. I will search forum for more info.

 

// A

Link to post
Share on other sites

Hi guys, thank you for quick reply.

 

 

Hi,

I altered by using either IFG or UCBUSY. After your recommendation I stick to UCBUSY. I changed the other parts of the code of how you recommended but the issue remains.

The mentioned C-code stated in the beginning works flawlessly. If I load this code first, I can successfully run my own code if I don't reinsert the board.

 

Did you look at the compilor assembly output in the .lst file for the C code?

 

That might give you a hint what's different.

 

Cyb

Link to post
Share on other sites

Did you look at the compilor assembly output in the .lst file for the C code?

 

That might give you a hint what's different.

 

Cyb

 

Yes, I did. Both gcc generated -S output as well as disassembled binary file.

I will review again and see what's different of essential parts.

 

Ty for suggestion.

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...