Holck 0 Posted March 18, 2013 Share Posted March 18, 2013 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 Quote Link to post Share on other sites
cyberman_ff 3 Posted March 19, 2013 Share Posted March 19, 2013 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 Holck 1 Quote Link to post Share on other sites
pabigot 355 Posted March 19, 2013 Share Posted March 19, 2013 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. Holck, roadrunner84 and bluehash 3 Quote Link to post Share on other sites
Holck 0 Posted March 19, 2013 Author Share Posted March 19, 2013 Hi guys, thank you for quick reply. The only reliable method I've found to wait until something is transmitted ismain_loop:bit.b #UCA0STAT, &UCBUSYjz main_loopThat 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 amov.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 likemov.b #UCSSEL_2|UCSWRST, UCA0CTL1As 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 Quote Link to post Share on other sites
cyberman_ff 3 Posted March 20, 2013 Share Posted March 20, 2013 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 Quote Link to post Share on other sites
Holck 0 Posted March 20, 2013 Author Share Posted March 20, 2013 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. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.