Jump to content
43oh

Rickta59

Members
  • Content Count

    1,135
  • Joined

  • Last visited

  • Days Won

    71

Reputation Activity

  1. Like
    Rickta59 got a reaction from amstan in Full-duplex hardware UART for launchpad   
    Now that I have a freshly minted uniarch version of msp430-gcc, I wanted to test it out and make sure the newly added support for the msp430g2553 chip really worked. I took my softserial full duplex code and twisted it around some to take advantage of gcc. I also exercised some of my favorite features of gcc, specifically templates, just to make sure they work in the uniarch version.
     
    Yeah, as I get further into the msp430 world I've decided I don't really like TI's version of eclipse + CDT too much. Along my path to enlightenment I have left the CCS blanket and wrapped myself in the latest Eclipse+CDT (Helios) with msp430-gcc running on Ubuntu. Unfortunately, the code below probably won't compile with CCS. However, I'm sure at some point someone will port the uniarch version of mspgcc over to cygwin.
     
    One of the nice thing about the 2553 vs the 2231 is the 2553 chip has a hardware UART builtin. No more stolen TimerA cycles for me. I'm doing the serial dance with hardware now. Attached you will find the code and a Makefile.
     
    Notes about hardware USCI UART: You have to flip your TX/RX jumpers on your launchpad. This has been talked about elsewhere on the forums. I'm just using a couple of F-M jumper wires going to my msp430g2553 on a breadboard.
     
    You can read the announcement about uniarch and support for the newer chips over on the mailing list:
    http://sourceforge.net/mailarchive/foru ... pgcc-users
     
    The latest version of the following source code can be found here: https://gist.github.com/969447
     
    I took a snapshot of the code:

    /** * usci_serial.cpp - simple example using USCI UART + ringbuffer + command line monitor * * This code was written to test the new uniarch version of msp430-gcc. I wanted * to make sure it could generate code for the msp430g2553 running on the TI * launchpad. * * This code mplements a command line interface over the USB-CDC serial at * 9600-8-N-1. To test you must swap the RX/TX pins on your launchpad to use * the hardware USCI UART. I disconnected those jumpers on my launchpad and used * a couple of F-M jumper wires to run the msp430g2553 from a breadboard. * P1.1=RXD and P1.2=TXD ( this is the opposite of the msp430g2231 default setup ) * * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ #include #include #include #include "config.h" #include "ringbuffer.h" #include "usci_serial.h" /** * create a ring buffer that holds up to 16 uint8_t bytes * * Note: you could change the ringbuffer_ui8_16 typedef to * make it smaller or larger, just be consistent with what * you provide the Serial template */ ringbuffer_ui8_16 usci_buffer = { 0, 0, { 0 } }; Serial usci0 = { usci_buffer }; /** * USCI0RX_ISR - USCI UART receive character ISR handler * * we get an interrupt when a new character arrives via * the USCI UART receive pin. We just stuff it into * our buffer and let the main routine consume it. */ interrupt(USCIAB0RX_VECTOR) USCI0RX_ISR(void) { /** * Note: a side effect of reading UCA0RXBUF * is the rx interrupt flag is cleared */ usci_buffer.push_back(UCA0RXBUF); } /** * main - echo back to the user whatever they type */ int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_16MHZ; // set DCO clock for MCLK and SMCLK DCOCTL = CALDCO_16MHZ; usci0.init(); __bis_SR_register(GIE); // interrupts enabled usci0.xmit("\r\nMSP430G2553 Monitor\r\n$ "); while (true) { while (!usci0.empty()) { volatile int c; c = usci0.recv(); usci0.xmit((uint8_t) c); } } }
     

    /** * config.h - configure baud rates, MCLK frequency * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ #ifndef CONFIG_H_ #define CONFIG_H_ #define F_CPU 16000000 // use calibrated 16MHZ clock #ifdef __MSPGCC__ #define _enable_interrupts() __bis_status_register(GIE) #define _disable_interrupts() __bic_status_register(GIE) #endif #endif
     

    /* * ringbuffer.h - template for a circular buffer * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ #ifndef RINGBUFFER_H_ #define RINGBUFFER_H_ /** * ringbuffer - a template based interrupt safe circular buffer structure with functions */ template struct ringbuffer { volatile int head; volatile int tail; volatile T buffer[MAX_ITEMS]; /** * empty() - checks the buffer for data * * returns true if empty, false if there is data */ inline bool empty() { bool isEmpty; _disable_interrupts(); // prevent inconsistent reads isEmpty = (head == tail); _enable_interrupts(); return isEmpty; } /** * push_back() - append a byte to the buffer is possible * assumed to be called from the recv interrupt */ inline void push_back(T c) { int i = (unsigned int) (head + 1) % MAX_ITEMS; if (i != tail) { buffer[head] = c; head = i; } } /** * pop_front() - remove a value from front of ring buffer */ inline T pop_front() { T c = -1; _disable_interrupts(); // disable interrupts to protect head and tail values // This prevents the RX_ISR from modifying them // while we are trying to read and modify // if the head isn't ahead of the tail, we don't have any characters if (head != tail) { c = (T) buffer[tail]; tail = (unsigned int) (tail + 1) % MAX_ITEMS; } _enable_interrupts(); // ok .. let everyone at them return c; } }; typedef ringbuffer ringbuffer_ui8_16; // ringbuffer, max of 16 uint8_t values typedef ringbuffer Ringbuffer_uint8_32; // ringbuffer, max of 32 uint8_t values #endif /* RINGBUFFER_H_ */

    /** * usci_serial.cpp - simple example using USCI UART + ringbuffer + command line monitor * * This code was written to test the new uniarch version of msp430-gcc. I wanted * to make sure it could generate code for the msp430g2553 running on the TI * launchpad. * * This code mplements a command line interface over the USB-CDC serial at * 9600-8-N-1. To test you must swap the RX/TX pins on your launchpad to use * the hardware USCI UART. I disconnected those jumpers on my launchpad and used * a couple of F-M jumper wires to run the msp430g2553 from a breadboard. * P1.1=RXD and P1.2=TXD ( this is the opposite of the msp430g2231 default setup ) * * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ #include #include #include #include "config.h" #include "ringbuffer.h" #include "usci_serial.h" /** * create a ring buffer that holds up to 16 uint8_t bytes * * Note: you could change the ringbuffer_ui8_16 typedef to * make it smaller or larger, just be consistent with what * you provide the Serial template */ ringbuffer_ui8_16 usci_buffer = { 0, 0, { 0 } }; Serial usci0 = { usci_buffer }; /** * USCI0RX_ISR - USCI UART receive character ISR handler * * we get an interrupt when a new character arrives via * the USCI UART receive pin. We just stuff it into * our buffer and let the main routine consume it. */ interrupt(USCIAB0RX_VECTOR) USCI0RX_ISR(void) { /** * Note: a side effect of reading UCA0RXBUF * is the rx interrupt flag is cleared */ usci_buffer.push_back(UCA0RXBUF); } /** * main - echo back to the user whatever they type */ int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_16MHZ; // set DCO clock for MCLK and SMCLK DCOCTL = CALDCO_16MHZ; usci0.init(); __bis_SR_register(GIE); // interrupts enabled usci0.xmit("\r\nMSP430G2553 Monitor\r\n$ "); while (true) { while (!usci0.empty()) { volatile int c; c = usci0.recv(); usci0.xmit((uint8_t) c); } } }
    #ifndef HW_SERIAL_H #define HW_SERIAL_H /** * Serial - simple access to USCI UART hardware * code implements interrupt driven input * and poll driven output. * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ template struct Serial { T_STORAGE &_recv_buffer; /** * init - setup the USCI UART hardware for 9600-8-N-1 * P1.1 = RX PIN, P1.2 = TX PIN */ inline void init() { P1SEL = BIT1 + BIT2; // P1.1=RXD, P1.2=TXD P1SEL2 = BIT1 + BIT2; // P1.1=RXD, P1.2=TXD UCA0CTL1 |= UCSSEL_2; // use SMCLK for USCI clock UCA0BR0 = 130; // 16MHz 9600 UCA0BR1 = 6; // 16MHz 9600 UCA0MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI0RX_ISR interrupt } inline bool empty() { return _recv_buffer.empty(); } inline int recv() { return _recv_buffer.pop_front(); } void xmit(uint8_t c) { while (!(IFG2 & UCA0TXIFG)) ; // USCI_A0 TX buffer ready? UCA0TXBUF = (uint8_t) c; // TX -> RXed character } void xmit(const char *s) { while (*s) { xmit((uint8_t) *s); ++s; } } }; #endif /* HW_SERIAL_H */

    # # Makefile - usci_serial # # License: Do with this code what you want. However, don't blame # me if you connect it to a heart pump and it stops. This source # is provided as is with no warranties. It probably has bugs!! # You have been warned! # # Author: Rick Kimball # email: rick@kimballsoftware.com # Version: 1.00 Initial version 05-12-2011 CC=msp430-gcc CXX=msp430-g++ MCU=msp430g2553 CFLAGS=-mmcu=$(MCU) -O2 -g -Wall APP=usci_serial TARGET=Debug all: $(TARGET)/$(APP).elf $(TARGET)/$(APP).elf: $(TARGET)/$(APP).o $(CC) $(CFLAGS) -o $(TARGET)/$(APP).elf $(TARGET)/$(APP).o msp430-objdump -DS $(TARGET)/$(APP).elf >$(TARGET)/$(APP).lst msp430-size $(TARGET)/$(APP).elf $(TARGET)/$(APP).o: config.h ringbuffer.h $(APP).cpp $(APP).h $(CC) $(CFLAGS) -c -o $(TARGET)/$(APP).o $(APP).cpp install: mspdebug -q --force-reset rf2500 "prog $(TARGET)/$(APP).elf" clean: rm -f $(TARGET)/$(APP).o $(TARGET)/$(APP).elf $(TARGET)/$(APP).lst mkdir -p $(TARGET)/
  2. Like
    Rickta59 got a reaction from bluehash in Full-duplex hardware UART for launchpad   
    Now that I have a freshly minted uniarch version of msp430-gcc, I wanted to test it out and make sure the newly added support for the msp430g2553 chip really worked. I took my softserial full duplex code and twisted it around some to take advantage of gcc. I also exercised some of my favorite features of gcc, specifically templates, just to make sure they work in the uniarch version.
     
    Yeah, as I get further into the msp430 world I've decided I don't really like TI's version of eclipse + CDT too much. Along my path to enlightenment I have left the CCS blanket and wrapped myself in the latest Eclipse+CDT (Helios) with msp430-gcc running on Ubuntu. Unfortunately, the code below probably won't compile with CCS. However, I'm sure at some point someone will port the uniarch version of mspgcc over to cygwin.
     
    One of the nice thing about the 2553 vs the 2231 is the 2553 chip has a hardware UART builtin. No more stolen TimerA cycles for me. I'm doing the serial dance with hardware now. Attached you will find the code and a Makefile.
     
    Notes about hardware USCI UART: You have to flip your TX/RX jumpers on your launchpad. This has been talked about elsewhere on the forums. I'm just using a couple of F-M jumper wires going to my msp430g2553 on a breadboard.
     
    You can read the announcement about uniarch and support for the newer chips over on the mailing list:
    http://sourceforge.net/mailarchive/foru ... pgcc-users
     
    The latest version of the following source code can be found here: https://gist.github.com/969447
     
    I took a snapshot of the code:

    /** * usci_serial.cpp - simple example using USCI UART + ringbuffer + command line monitor * * This code was written to test the new uniarch version of msp430-gcc. I wanted * to make sure it could generate code for the msp430g2553 running on the TI * launchpad. * * This code mplements a command line interface over the USB-CDC serial at * 9600-8-N-1. To test you must swap the RX/TX pins on your launchpad to use * the hardware USCI UART. I disconnected those jumpers on my launchpad and used * a couple of F-M jumper wires to run the msp430g2553 from a breadboard. * P1.1=RXD and P1.2=TXD ( this is the opposite of the msp430g2231 default setup ) * * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ #include #include #include #include "config.h" #include "ringbuffer.h" #include "usci_serial.h" /** * create a ring buffer that holds up to 16 uint8_t bytes * * Note: you could change the ringbuffer_ui8_16 typedef to * make it smaller or larger, just be consistent with what * you provide the Serial template */ ringbuffer_ui8_16 usci_buffer = { 0, 0, { 0 } }; Serial usci0 = { usci_buffer }; /** * USCI0RX_ISR - USCI UART receive character ISR handler * * we get an interrupt when a new character arrives via * the USCI UART receive pin. We just stuff it into * our buffer and let the main routine consume it. */ interrupt(USCIAB0RX_VECTOR) USCI0RX_ISR(void) { /** * Note: a side effect of reading UCA0RXBUF * is the rx interrupt flag is cleared */ usci_buffer.push_back(UCA0RXBUF); } /** * main - echo back to the user whatever they type */ int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_16MHZ; // set DCO clock for MCLK and SMCLK DCOCTL = CALDCO_16MHZ; usci0.init(); __bis_SR_register(GIE); // interrupts enabled usci0.xmit("\r\nMSP430G2553 Monitor\r\n$ "); while (true) { while (!usci0.empty()) { volatile int c; c = usci0.recv(); usci0.xmit((uint8_t) c); } } }
     

    /** * config.h - configure baud rates, MCLK frequency * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ #ifndef CONFIG_H_ #define CONFIG_H_ #define F_CPU 16000000 // use calibrated 16MHZ clock #ifdef __MSPGCC__ #define _enable_interrupts() __bis_status_register(GIE) #define _disable_interrupts() __bic_status_register(GIE) #endif #endif
     

    /* * ringbuffer.h - template for a circular buffer * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ #ifndef RINGBUFFER_H_ #define RINGBUFFER_H_ /** * ringbuffer - a template based interrupt safe circular buffer structure with functions */ template struct ringbuffer { volatile int head; volatile int tail; volatile T buffer[MAX_ITEMS]; /** * empty() - checks the buffer for data * * returns true if empty, false if there is data */ inline bool empty() { bool isEmpty; _disable_interrupts(); // prevent inconsistent reads isEmpty = (head == tail); _enable_interrupts(); return isEmpty; } /** * push_back() - append a byte to the buffer is possible * assumed to be called from the recv interrupt */ inline void push_back(T c) { int i = (unsigned int) (head + 1) % MAX_ITEMS; if (i != tail) { buffer[head] = c; head = i; } } /** * pop_front() - remove a value from front of ring buffer */ inline T pop_front() { T c = -1; _disable_interrupts(); // disable interrupts to protect head and tail values // This prevents the RX_ISR from modifying them // while we are trying to read and modify // if the head isn't ahead of the tail, we don't have any characters if (head != tail) { c = (T) buffer[tail]; tail = (unsigned int) (tail + 1) % MAX_ITEMS; } _enable_interrupts(); // ok .. let everyone at them return c; } }; typedef ringbuffer ringbuffer_ui8_16; // ringbuffer, max of 16 uint8_t values typedef ringbuffer Ringbuffer_uint8_32; // ringbuffer, max of 32 uint8_t values #endif /* RINGBUFFER_H_ */

    /** * usci_serial.cpp - simple example using USCI UART + ringbuffer + command line monitor * * This code was written to test the new uniarch version of msp430-gcc. I wanted * to make sure it could generate code for the msp430g2553 running on the TI * launchpad. * * This code mplements a command line interface over the USB-CDC serial at * 9600-8-N-1. To test you must swap the RX/TX pins on your launchpad to use * the hardware USCI UART. I disconnected those jumpers on my launchpad and used * a couple of F-M jumper wires to run the msp430g2553 from a breadboard. * P1.1=RXD and P1.2=TXD ( this is the opposite of the msp430g2231 default setup ) * * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ #include #include #include #include "config.h" #include "ringbuffer.h" #include "usci_serial.h" /** * create a ring buffer that holds up to 16 uint8_t bytes * * Note: you could change the ringbuffer_ui8_16 typedef to * make it smaller or larger, just be consistent with what * you provide the Serial template */ ringbuffer_ui8_16 usci_buffer = { 0, 0, { 0 } }; Serial usci0 = { usci_buffer }; /** * USCI0RX_ISR - USCI UART receive character ISR handler * * we get an interrupt when a new character arrives via * the USCI UART receive pin. We just stuff it into * our buffer and let the main routine consume it. */ interrupt(USCIAB0RX_VECTOR) USCI0RX_ISR(void) { /** * Note: a side effect of reading UCA0RXBUF * is the rx interrupt flag is cleared */ usci_buffer.push_back(UCA0RXBUF); } /** * main - echo back to the user whatever they type */ int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_16MHZ; // set DCO clock for MCLK and SMCLK DCOCTL = CALDCO_16MHZ; usci0.init(); __bis_SR_register(GIE); // interrupts enabled usci0.xmit("\r\nMSP430G2553 Monitor\r\n$ "); while (true) { while (!usci0.empty()) { volatile int c; c = usci0.recv(); usci0.xmit((uint8_t) c); } } }
    #ifndef HW_SERIAL_H #define HW_SERIAL_H /** * Serial - simple access to USCI UART hardware * code implements interrupt driven input * and poll driven output. * * License: Do with this code what you want. However, don't blame * me if you connect it to a heart pump and it stops. This source * is provided as is with no warranties. It probably has bugs!! * You have been warned! * * Author: Rick Kimball * email: rick@kimballsoftware.com * Version: 1.00 Initial version 05-12-2011 */ template struct Serial { T_STORAGE &_recv_buffer; /** * init - setup the USCI UART hardware for 9600-8-N-1 * P1.1 = RX PIN, P1.2 = TX PIN */ inline void init() { P1SEL = BIT1 + BIT2; // P1.1=RXD, P1.2=TXD P1SEL2 = BIT1 + BIT2; // P1.1=RXD, P1.2=TXD UCA0CTL1 |= UCSSEL_2; // use SMCLK for USCI clock UCA0BR0 = 130; // 16MHz 9600 UCA0BR1 = 6; // 16MHz 9600 UCA0MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI0RX_ISR interrupt } inline bool empty() { return _recv_buffer.empty(); } inline int recv() { return _recv_buffer.pop_front(); } void xmit(uint8_t c) { while (!(IFG2 & UCA0TXIFG)) ; // USCI_A0 TX buffer ready? UCA0TXBUF = (uint8_t) c; // TX -> RXed character } void xmit(const char *s) { while (*s) { xmit((uint8_t) *s); ++s; } } }; #endif /* HW_SERIAL_H */

    # # Makefile - usci_serial # # License: Do with this code what you want. However, don't blame # me if you connect it to a heart pump and it stops. This source # is provided as is with no warranties. It probably has bugs!! # You have been warned! # # Author: Rick Kimball # email: rick@kimballsoftware.com # Version: 1.00 Initial version 05-12-2011 CC=msp430-gcc CXX=msp430-g++ MCU=msp430g2553 CFLAGS=-mmcu=$(MCU) -O2 -g -Wall APP=usci_serial TARGET=Debug all: $(TARGET)/$(APP).elf $(TARGET)/$(APP).elf: $(TARGET)/$(APP).o $(CC) $(CFLAGS) -o $(TARGET)/$(APP).elf $(TARGET)/$(APP).o msp430-objdump -DS $(TARGET)/$(APP).elf >$(TARGET)/$(APP).lst msp430-size $(TARGET)/$(APP).elf $(TARGET)/$(APP).o: config.h ringbuffer.h $(APP).cpp $(APP).h $(CC) $(CFLAGS) -c -o $(TARGET)/$(APP).o $(APP).cpp install: mspdebug -q --force-reset rf2500 "prog $(TARGET)/$(APP).elf" clean: rm -f $(TARGET)/$(APP).o $(TARGET)/$(APP).elf $(TARGET)/$(APP).lst mkdir -p $(TARGET)/
  3. Like
    Rickta59 got a reaction from Tribes in Full-duplex software UART for launchpad   
    So this code snippet springs forth from my desire to use a terminal emulator ( I like putty best ) with my launchpad via the built-in COM port. Simple I think, someone must have already done this by now, no? Well, trying to find a working example for the launchpad led me down a lot of dead ends with nothing that worked well. I did find examples that were half-duplex and ones that required more Timer features than you find on the msp430g2231. Unfortunately, none of them fit my requirements.
     
    My goal was to find something that would allow me to use higher DCO clock speeds such as 16MHZ. I also wanted to be able to run reliably with 115k baud rates, so that I can connect a serial to TCP proxy and make my launchpad web enabled.
     
    I've implemented something here that meets both of those goals. Well sort of. I discovered that the COM port on the launchpad will only work up to 9600 baud. However, you can disconnect the jumpers and plug your RX/TX lines into an FT232RL device and get higher speeds. It also works well if your goal is to interface to some other device via TTL level RS232, say a GPS device.
     
    You can find the code here:
     
    https://github.com/RickKimball/msp430softserial
     
    Because everything is better with pictures, I took a snapshot of the RX line receiving the character 'U' at 9600 baud. 'U' is unique in that it forms a perfect clock wave 0 10101010 1 when you add the stop and start bits. The green line is the RX line, the red line is me toggling a debug pin inside of the RX ISR routine. I used a program called Soundcard Oscilloscope that helped me dial in the proper timing so that I was sampling in the center of each data bit. http://www.zeitnitz.de/Christian/scope_en
     

     
    In the picture above, you'll notice that the first red crossing takes longer than the other samplings, that is because we just ignore the value of the start bit and start sampling in the center of the first data bit.
     
    To use and test the code, download it from github and bring it into CCS. Once it is running figure out which COM port your launchpad is using and connect to it with a terminal emulator like putty or minicom using 9600 baud. The default configuration expects you to have soldered a 32.768k crystal to the launchpad board. It uses the crystal to calibrate the DCO for a higher MHZ speed. Don't worry, I don't write it to flash, I just calibrate it and use it. However, you can edit the config.h to modify the baud rate and MCLK speed. You can even run it at the default MCLK speed. See the config.h file comments for more information.
     
    I think I've commented the code fairly well. However, this is actually my first published project with the MSP430 launchpad so comments are welcome. So enjoy!
     
    -rick
  4. Like
    Rickta59 got a reaction from timsoer in Use a 12MHZ external square wave as MCLK   
    I've been looking for a way to run the msp430 with accurate MHZ speeds. In talking
    with NatureTM on IRC, he mentioned that he had used a crystal oscillator ( ECS-100A-160 ) successfully
    with his msp430g2231. He didn't have the exact code he used but he helped me recreate this snippet.
     
    I didn't have a crystal oscillator but I did have an ATTiny84 lying around that I put on a breadboard.
    I reprogrammed the ATTiny84 fuses so its CLKOUT fuse bit was enabled. The ATTiny is using an external
    12MHZ crystal. This is fairly accurate, when you enable the CLKOUT fuse, avr outputs the
    CPU clock on that pin as a square wave. I connected that pin to the XIN on my msp430g2231
    and left XOUT unconnected.
     
    I'm not sure if this is going to damage my g2231 as the specs say you should only feed it low
    frequency external square waves from 10k - 50k. So don't expect this to actually work. I'm
    just passing along what I've discovered.
     
    https://gist.github.com/954778
     
    -rick
     

    //*********************************************************** // runfast.c - Using 12MHZ external square wave clock as LFXTCLK // source MCLK/SMCLK from 12MHZ wave and blink led // at 60Hz // // Use an external clock ( I'm using an attiny running at 12.00 MHZ // with the CLKOUT fuse enabled ) as the MCLK/SMCLK for the MSP430. // I've been told you could also use an external oscillator like an // ECS-100A-160. I ordered some of these to verify. // // LFXT1 oscillator logic level square wave input frequency, LF mode // // XIN - external clock in from attiny CLKOUT pin ( set avr fuse to get clock ) // XOUT - NC // P1.0 - led on until OSCFault cleared // P1.4 - SMCLK frequency, measuer with multimeter/oscope // P1.6 - 60Hz led flash, measure with multimeter/oscope // //*********************************************************** #include void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR = BIT0 | BIT6 | BIT4; // P1.0 and P1.6 output, P1.4 SMCLK frequency P1SEL = BIT4; // P1.4 output SMCLK on P1.4, measure with multi meter P1OUT = BIT0; // red LED on until OSCFault is cleared DCOCTL = 0x00; BCSCTL2 = SELM_3 + DIVM_0 + SELS + DIVS_0; // MCLK Source Select 3: LFXTCLK // MCLK/1 SMCLK/1 SMCLK LFXTCLK BCSCTL1 |= XTS; // XTS BCSCTL3 = LFXT1S_3 | XCAP_0; // LFXT1 = 12MHZ crystal, No Capacitor // not sure if this is needed while(IFG1 & OFIFG) { IFG1 &= ~OFIFG; // Clear OSCFault flag _delay_cycles(10000); // delay for flag and visibility } P1OUT = 0; // red LED off __bis_SR_register(SCG0); // Stop DCO, we just use the LFXT1 which is // actually running at 12MHZ while(1) { P1OUT ^= BIT6; // green LED on, measure this, it should be 60Hz _delay_cycles((12000000/60/2)-35); // 12MHZ, 60/2, 35 overhead clocks } }
  5. Like
    Rickta59 reacted to NatureTM in Launchpad TV output   
    I went to a white elephant "The Office" watching party last Thursday. I gave my TVOut demo with the emergency broadcast system screen as my white elephant gift. Anyway, it got me looking at the code again. I realized it would be really easy to increase the resolution now that we have chips with greater than 2K flash.
     
    I pretty much changed two lines of code, created some new images, and uploaded it to an MSP430G2452 with 8K. The resolution is now 192x240. It's still a funky aspect ratio limited by code space and USI frequency, but I expect to get it to do 384x240 when I get my hands on one of the new 16K chips. I also realized I had some really goofy code due to a misunderstanding of pointers. I fixed that, and it no longer needs to compile as C++.
     

    /* Monochrome NTSC composite video output for TI's Launchpad. * * Schmatic: * 470 * P1.2 SYNC --------/\/\/\--------| * |----- RCA jack Signal * 220 | * P1.6 VOUT --------/\/\/\--------| * * Launchpad GND ------------------------ RCA jack GND * * * By: NatureTM * more info on naturetm.com */ #include #define TACCR0 TA0CCR0 #define TACCR1 TA0CCR1 #define TACCTL0 TA0CCTL0 #define TACCTL1 TA0CCTL1 #define TIMERA0_VECTOR TIMER0_A0_VECTOR #define TIMERA1_VECTOR TIMER0_A1_VECTOR // Image file #include "teh_real_nature.h" //#include "gina_close.h" //#include "gina_wide.h" //#include "ebs2.h" #define SYNC BIT2 #define VOUT BIT6 //#define NS_TICK 62.5 // NS = nanoseconds #define TICKS_HSYNC 72 #define TICKS_SHORT_SYNC 38 #define TICKS_HBLANK 163 #define TICKS_SCANLINE 1017 #define TICKS_HALF_SCANLINE 508 #define TICKS_RIGHT_EDGE 973 #define ROW_HEIGHT 1 // in scanlines #define WORDS_SCANLINE 12 unsigned int* currentRowPtr; unsigned int imageOffset; unsigned int scanline = 0; char imageLine; char subRowCounter; unsigned int sleep; int main(){ DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; WDTCTL = WDTPW + WDTHOLD; // Stop WDT _BIS_SR(GIE); //enable interrupts USICKCTL = USIDIV1 + USISSEL1 + USISSEL0;// + USICKPL; // USI Clock = SMCLK / 4 USICNT = USI16B; // 16 bit shift out USICTL0 |= USIMST; // Use internal clock source USICTL0 &= ~USISWRST; // Clear USI reset bit (enable USI) USICTL0 |= USILSB; // USISR output LSB first USICTL0 |= USIGE; TACTL |= MC_0; // Stop timer A TACTL |= TASSEL1; // TASrc = SMClk = MClk TACTL &= ~TASSEL0; TACTL |= TACLR; // Clear the timer CCR0 = TICKS_SCANLINE; // Scanline timing - CCR0 triggers hSync CCR1 = TICKS_HSYNC; // End of hSync TACTL |= MC_1; // Up mode, Start TACCTL0 |= CCIE; // Enable Timer A CCR0 interrupt TACCTL1 |= OUTMOD_3; // TimerA reset sync pin on CCR0 TACCTL1 |= CCIE; // Enable Timer A CCR1 interrupt P1SEL = SYNC; // Allow timerA to set sync pin low on beginning of scanline P1DIR = SYNC + VOUT + BIT5; } // vsync broad sync pulse section void vSyncTripleBroad(){ int count; for(count = 0; count < 3; count++){ while(TAR < TICKS_HALF_SCANLINE - TICKS_HSYNC){} P1OUT = SYNC; while(TAR < TICKS_HALF_SCANLINE){} P1OUT = 0; while(TAR < TICKS_SCANLINE - TICKS_HSYNC){} P1OUT = SYNC; while(TAR > TICKS_SCANLINE - TICKS_HSYNC){} P1OUT = 0; } } // vsync short sync pulse section void vSyncTripleShort(){ int count; for (count = 0; count < 3; count++){ while(TAR < TICKS_SHORT_SYNC){} P1OUT = SYNC; while(TAR < TICKS_HALF_SCANLINE){} P1OUT = 0; while(TAR < TICKS_HALF_SCANLINE + TICKS_SHORT_SYNC){} P1OUT = SYNC; while(TAR > TICKS_HALF_SCANLINE + TICKS_SHORT_SYNC){} P1OUT = 0; } } // This ISR is run at the beginning of every scanline and keeps track of which // scanline we are on. At the beginning of a frame, it handles vSync output in // software. Next, it hands over control of the sync pin to TimerA, allowing // hsync timing to be done in hardware. #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A0 (void){ // software vSync if(scanline == 0){ P1OUT = 0; P1SEL = 0; // let software control P1.5 instead of TACCR0 vSyncTripleShort(); vSyncTripleBroad(); vSyncTripleShort(); scanline = 8; // vSync takes several scanlines P1SEL = SYNC; // let TimerA handle hSync } // visible area starts/vBlank over else if(scanline == 21){ scanline++; TACCTL1 |= CCIE; // Start drawing picture subRowCounter = 0; imageOffset = 0; } else if(scanline < 263){ scanline++; } // bottom of screen, get ready for vSync else{ TACCTL1 &= ~CCIE; // Stop drawing picture scanline = 0; } } // After vSync, this ISR begins USI output of the image. #pragma vector=TIMERA1_VECTOR __interrupt void Timer_A1 (void){ int wordCounter = 0; TAIV = 0; // Clear TimerA's interrupt vector register; USICTL0 |= USIOE; // USI output enabled USICTL0 |= USIPE6; // Port 1.6 USI data out while (TAR < TICKS_HBLANK){} do{ USICNT |= 16; USISR = currentRowPtr[wordCounter]; wordCounter++; // software delay allowing full USI shift out sleep = 0; while(sleep < 2) sleep++; _nop(); _nop(); _nop(); _nop(); _nop(); _nop(); _nop(); }while(wordCounter < WORDS_SCANLINE); if(subRowCounter == ROW_HEIGHT){ subRowCounter = 0; imageOffset += WORDS_SCANLINE; } subRowCounter++; currentRowPtr = (unsigned int*)image + imageOffset; while(TAR < TICKS_RIGHT_EDGE){} // Wait for edge of screen USICTL0 &= ~(USIPE6 + USIOE); // Release control of video pin to software }
     
    It needs to be flashed in CCS under Debug mode (without optimizations.) Compiling in Release mode with optimizations leads to distorted video. It probably could be fixed for release mode or mspgcc by tweaking the software delay toward the bottom. Changing that "sleep" variable to volatile might just be enough (a thought I had just now, not tested.)
     
    Files, demo images, and information on how to create your own images available on my bloggity-bloggy-blog. I find the word blog amusing.
    http://naturetm.com/?p=147
  6. Like
    Rickta59 got a reaction from oPossum in Full-duplex software UART for launchpad   
    So this code snippet springs forth from my desire to use a terminal emulator ( I like putty best ) with my launchpad via the built-in COM port. Simple I think, someone must have already done this by now, no? Well, trying to find a working example for the launchpad led me down a lot of dead ends with nothing that worked well. I did find examples that were half-duplex and ones that required more Timer features than you find on the msp430g2231. Unfortunately, none of them fit my requirements.
     
    My goal was to find something that would allow me to use higher DCO clock speeds such as 16MHZ. I also wanted to be able to run reliably with 115k baud rates, so that I can connect a serial to TCP proxy and make my launchpad web enabled.
     
    I've implemented something here that meets both of those goals. Well sort of. I discovered that the COM port on the launchpad will only work up to 9600 baud. However, you can disconnect the jumpers and plug your RX/TX lines into an FT232RL device and get higher speeds. It also works well if your goal is to interface to some other device via TTL level RS232, say a GPS device.
     
    You can find the code here:
     
    https://github.com/RickKimball/msp430softserial
     
    Because everything is better with pictures, I took a snapshot of the RX line receiving the character 'U' at 9600 baud. 'U' is unique in that it forms a perfect clock wave 0 10101010 1 when you add the stop and start bits. The green line is the RX line, the red line is me toggling a debug pin inside of the RX ISR routine. I used a program called Soundcard Oscilloscope that helped me dial in the proper timing so that I was sampling in the center of each data bit. http://www.zeitnitz.de/Christian/scope_en
     

     
    In the picture above, you'll notice that the first red crossing takes longer than the other samplings, that is because we just ignore the value of the start bit and start sampling in the center of the first data bit.
     
    To use and test the code, download it from github and bring it into CCS. Once it is running figure out which COM port your launchpad is using and connect to it with a terminal emulator like putty or minicom using 9600 baud. The default configuration expects you to have soldered a 32.768k crystal to the launchpad board. It uses the crystal to calibrate the DCO for a higher MHZ speed. Don't worry, I don't write it to flash, I just calibrate it and use it. However, you can edit the config.h to modify the baud rate and MCLK speed. You can even run it at the default MCLK speed. See the config.h file comments for more information.
     
    I think I've commented the code fairly well. However, this is actually my first published project with the MSP430 launchpad so comments are welcome. So enjoy!
     
    -rick
  7. Like
    Rickta59 got a reaction from GeekDoc in Full-duplex software UART for launchpad   
    I just updated the code so that it works with chips that have multiple TimerA peripherals, like the msp430g2553.
     
    https://github.com/RickKimball/msp430softserial
     
     
    -rick
  8. Like
    Rickta59 got a reaction from bluehash in Full-duplex software UART for launchpad   
    I just updated the code so that it works with chips that have multiple TimerA peripherals, like the msp430g2553.
     
    https://github.com/RickKimball/msp430softserial
     
     
    -rick
  9. Like
    Rickta59 got a reaction from gordon in Full-duplex software UART for launchpad   
    So this code snippet springs forth from my desire to use a terminal emulator ( I like putty best ) with my launchpad via the built-in COM port. Simple I think, someone must have already done this by now, no? Well, trying to find a working example for the launchpad led me down a lot of dead ends with nothing that worked well. I did find examples that were half-duplex and ones that required more Timer features than you find on the msp430g2231. Unfortunately, none of them fit my requirements.
     
    My goal was to find something that would allow me to use higher DCO clock speeds such as 16MHZ. I also wanted to be able to run reliably with 115k baud rates, so that I can connect a serial to TCP proxy and make my launchpad web enabled.
     
    I've implemented something here that meets both of those goals. Well sort of. I discovered that the COM port on the launchpad will only work up to 9600 baud. However, you can disconnect the jumpers and plug your RX/TX lines into an FT232RL device and get higher speeds. It also works well if your goal is to interface to some other device via TTL level RS232, say a GPS device.
     
    You can find the code here:
     
    https://github.com/RickKimball/msp430softserial
     
    Because everything is better with pictures, I took a snapshot of the RX line receiving the character 'U' at 9600 baud. 'U' is unique in that it forms a perfect clock wave 0 10101010 1 when you add the stop and start bits. The green line is the RX line, the red line is me toggling a debug pin inside of the RX ISR routine. I used a program called Soundcard Oscilloscope that helped me dial in the proper timing so that I was sampling in the center of each data bit. http://www.zeitnitz.de/Christian/scope_en
     

     
    In the picture above, you'll notice that the first red crossing takes longer than the other samplings, that is because we just ignore the value of the start bit and start sampling in the center of the first data bit.
     
    To use and test the code, download it from github and bring it into CCS. Once it is running figure out which COM port your launchpad is using and connect to it with a terminal emulator like putty or minicom using 9600 baud. The default configuration expects you to have soldered a 32.768k crystal to the launchpad board. It uses the crystal to calibrate the DCO for a higher MHZ speed. Don't worry, I don't write it to flash, I just calibrate it and use it. However, you can edit the config.h to modify the baud rate and MCLK speed. You can even run it at the default MCLK speed. See the config.h file comments for more information.
     
    I think I've commented the code fairly well. However, this is actually my first published project with the MSP430 launchpad so comments are welcome. So enjoy!
     
    -rick
  10. Like
    Rickta59 got a reaction from GeekDoc in Full-duplex software UART for launchpad   
    So this code snippet springs forth from my desire to use a terminal emulator ( I like putty best ) with my launchpad via the built-in COM port. Simple I think, someone must have already done this by now, no? Well, trying to find a working example for the launchpad led me down a lot of dead ends with nothing that worked well. I did find examples that were half-duplex and ones that required more Timer features than you find on the msp430g2231. Unfortunately, none of them fit my requirements.
     
    My goal was to find something that would allow me to use higher DCO clock speeds such as 16MHZ. I also wanted to be able to run reliably with 115k baud rates, so that I can connect a serial to TCP proxy and make my launchpad web enabled.
     
    I've implemented something here that meets both of those goals. Well sort of. I discovered that the COM port on the launchpad will only work up to 9600 baud. However, you can disconnect the jumpers and plug your RX/TX lines into an FT232RL device and get higher speeds. It also works well if your goal is to interface to some other device via TTL level RS232, say a GPS device.
     
    You can find the code here:
     
    https://github.com/RickKimball/msp430softserial
     
    Because everything is better with pictures, I took a snapshot of the RX line receiving the character 'U' at 9600 baud. 'U' is unique in that it forms a perfect clock wave 0 10101010 1 when you add the stop and start bits. The green line is the RX line, the red line is me toggling a debug pin inside of the RX ISR routine. I used a program called Soundcard Oscilloscope that helped me dial in the proper timing so that I was sampling in the center of each data bit. http://www.zeitnitz.de/Christian/scope_en
     

     
    In the picture above, you'll notice that the first red crossing takes longer than the other samplings, that is because we just ignore the value of the start bit and start sampling in the center of the first data bit.
     
    To use and test the code, download it from github and bring it into CCS. Once it is running figure out which COM port your launchpad is using and connect to it with a terminal emulator like putty or minicom using 9600 baud. The default configuration expects you to have soldered a 32.768k crystal to the launchpad board. It uses the crystal to calibrate the DCO for a higher MHZ speed. Don't worry, I don't write it to flash, I just calibrate it and use it. However, you can edit the config.h to modify the baud rate and MCLK speed. You can even run it at the default MCLK speed. See the config.h file comments for more information.
     
    I think I've commented the code fairly well. However, this is actually my first published project with the MSP430 launchpad so comments are welcome. So enjoy!
     
    -rick
  11. Like
    Rickta59 got a reaction from jsolarski in Full-duplex software UART for launchpad   
    So this code snippet springs forth from my desire to use a terminal emulator ( I like putty best ) with my launchpad via the built-in COM port. Simple I think, someone must have already done this by now, no? Well, trying to find a working example for the launchpad led me down a lot of dead ends with nothing that worked well. I did find examples that were half-duplex and ones that required more Timer features than you find on the msp430g2231. Unfortunately, none of them fit my requirements.
     
    My goal was to find something that would allow me to use higher DCO clock speeds such as 16MHZ. I also wanted to be able to run reliably with 115k baud rates, so that I can connect a serial to TCP proxy and make my launchpad web enabled.
     
    I've implemented something here that meets both of those goals. Well sort of. I discovered that the COM port on the launchpad will only work up to 9600 baud. However, you can disconnect the jumpers and plug your RX/TX lines into an FT232RL device and get higher speeds. It also works well if your goal is to interface to some other device via TTL level RS232, say a GPS device.
     
    You can find the code here:
     
    https://github.com/RickKimball/msp430softserial
     
    Because everything is better with pictures, I took a snapshot of the RX line receiving the character 'U' at 9600 baud. 'U' is unique in that it forms a perfect clock wave 0 10101010 1 when you add the stop and start bits. The green line is the RX line, the red line is me toggling a debug pin inside of the RX ISR routine. I used a program called Soundcard Oscilloscope that helped me dial in the proper timing so that I was sampling in the center of each data bit. http://www.zeitnitz.de/Christian/scope_en
     

     
    In the picture above, you'll notice that the first red crossing takes longer than the other samplings, that is because we just ignore the value of the start bit and start sampling in the center of the first data bit.
     
    To use and test the code, download it from github and bring it into CCS. Once it is running figure out which COM port your launchpad is using and connect to it with a terminal emulator like putty or minicom using 9600 baud. The default configuration expects you to have soldered a 32.768k crystal to the launchpad board. It uses the crystal to calibrate the DCO for a higher MHZ speed. Don't worry, I don't write it to flash, I just calibrate it and use it. However, you can edit the config.h to modify the baud rate and MCLK speed. You can even run it at the default MCLK speed. See the config.h file comments for more information.
     
    I think I've commented the code fairly well. However, this is actually my first published project with the MSP430 launchpad so comments are welcome. So enjoy!
     
    -rick
×
×
  • Create New...