• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » UART TX/RX Interrupt Problem on CC430F6137
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • UART TX/RX Interrupt Problem on CC430F6137

    UART TX/RX Interrupt Problem on CC430F6137

    This question is not answered
    William Heavin
    Posted by William Heavin
    on Apr 12 2012 06:19 AM
    Prodigy30 points

    Hi

    I'm using two cc430f6137 boards to communicate over a SimpliciTI link. Both boards are linked to computers using UART links and I'm using RealTerm to send and receive bytes. My baud rate is 57600 at 1MHz. My code is based on the EZ-Chat application by Brandon Elliott and Harman Grewal for the EZ430 which I have modified to suit my needs.

    My main_LinkTo.c code looks like this:

    // EZ-Chat
    // Brandon Elliott / Harman Grewal
    // June 2009
    /********************************************************************************************
     Chat Program -- Link to
     **************************************************************************************************/
    //#include <cc430f6137.h>

    #include "bsp.h"
    #include "mrfi.h"
    #include "nwk_types.h"
    #include "nwk_api.h"
    #include "bsp_leds.h"
    #include "bsp_buttons.h"

    #include "app_remap_led.h"

    //smplStatus_t STATUS;
    static uint8_t sRxTid = 0;
    static linkID_t sLinkID1 = 0;

    static volatile uint8_t sSemaphore = 0;
    #define SPIN_ABOUT_A_SECOND  NWK_DELAY(1000)
    #define DELAY  NWK_DELAY(100)

    void DisplayCharacter(uint8_t[], char);
    void initUART(void);
    void toggleLED(uint8_t);

    static void linkTo(void);
    static uint8_t sRxCallback(linkID_t);

    void tx_char(uint8_t *, int*);
    void rx_char(void);

    volatile char Temp_Size;

    static uint8_t key;
    char Key_Not_Pressed, TxHold = 1;
    //char txing = 0;
    char Buffer[50] = { 0 };
    //uint8_t name[11] = "Jim: ";
    int new_msg = 0;

    void main(void) {
        BSP_Init();                        // init board and drivers
        SMPL_Init(sRxCallback);            // init simpliciTI

        initUART();
        uint8_t opening_msg[] = "press key to link\r\n\r\n ";
        Temp_Size = sizeof(opening_msg);
        DisplayCharacter(opening_msg, Temp_Size);

        /* turn on LEDs. */
        if (!BSP_LED2_IS_ON())
        {
            toggleLED(2);                    // Toggle LED 2
        }
        if (!BSP_LED1_IS_ON())
        {
            toggleLED(1);                    // Toggle LED 1
        }

        // loop waiting for button press
        while (1) {
            if (BSP_BUTTON1() || BSP_BUTTON2())
            {
                break;
            }
        }

        linkTo();   // no return
        while (1)    // loop just in case
            ;
    }

    static void linkTo() {
        uint8_t msg[2], tid, rxmsg[2];
        int count = 0;

        // listen for link forever...
        while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) {
            /* blink LEDs until we link successfully */
            toggleLED(1);
            toggleLED(2);
            SPIN_ABOUT_A_SECOND;
        }

        /* we're linked. turn off red LED. received messages will toggle the green LED. */
        if (BSP_LED2_IS_ON())
        {
            toggleLED(2);
        }

        uint8_t array[] = "CONNECTED - Link To\r\n\r\n"; // Connection Established, display msg to hyperterminal
        Temp_Size = sizeof(array);
        DisplayCharacter(array, Temp_Size);                // Send connected message
        SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
        //initUART();
        int * countptr;
        countptr = &count;
        uint8_t* char_var;
        char_var = &msg[0];
        DELAY;

        while (1) {
            tx_char(char_var, countptr); // Transmit

            if (sSemaphore) {
                *(rxmsg + 1) = ++tid;
                SMPL_Send(sLinkID1, rxmsg, 2);
                /* Reset semaphore. This is not properly protected and there is a race
                 * here. In theory we could miss a message. Good enough for a demo, though.
                 */
                sSemaphore = 0;
            }
        }
    }

    void toggleLED(uint8_t which) {
        if (1 == which) {
            BSP_TOGGLE_LED1();
        } else if (2 == which) {
            BSP_TOGGLE_LED2();
        }
        return;
    }

    void tx_char(uint8_t *msg_ptr, int *count) {
        uint8_t rxmsg[2], array[1];
        uint8_t tid = 0;

        unsigned int i;

        while ((Key_Not_Pressed))
            ; //Wait for a key press from the user
        if (*count > 35) {
            TxHold = 0;
            //wait_message = 1;
        }

        Buffer[*count] = key;
        (*count)++;
        /*if (*count == 1) {
            int Temp_Size = sizeof(name);
            DisplayCharacter(name, Temp_Size);
        }*/
        array[1] = key;
        DisplayCharacter(array, 1);

        if (sSemaphore) {
            *(rxmsg + 1) = ++tid;
            SMPL_Send(sLinkID1, rxmsg, 2);
            sSemaphore = 0;
        }

        if (!TxHold) {
            Buffer[*count] = 0x12;
            /*uint8_t queue[1];
            for (j = 0; j < 10; j++) {
                queue[0] = name[j];
                SMPL_Send(sLinkID1, queue, 2);
            }*/
            for (i = 0; i < *count; i++) {
                msg_ptr[0] = Buffer[i];
                SMPL_Send(sLinkID1, msg_ptr, 2);
            }
            new_msg = 0;
            uint8_t array5[] = "\r\n";
            int Temp_Size = sizeof(array5);
            DisplayCharacter(array5, Temp_Size);
            TxHold = 1;
            *count = 0;
        }

        Key_Not_Pressed = 1;
    }

    /* handle received frames. */
    static uint8_t sRxCallback(linkID_t port) {
        uint8_t msg[2], len, tid;
        if (port == sLinkID1) {
            if ((SMPL_SUCCESS == SMPL_Receive(sLinkID1, msg, &len)) && len) {
                if (msg[0] == 0x0D) {
                    new_msg = 1;
                    uint8_t array2[] = "\r\n\r\n";
                    Temp_Size = sizeof(array2);
                    DisplayCharacter(array2, Temp_Size);
                }
                if (msg[0] < 0x80) {
                    DisplayCharacter(msg, 1);
                    toggleLED(2);
                }

                /* Check the application sequence number to detect
                 * late or missing frames...*/

                tid = *(msg + 1);
                if (tid) {
                    if (tid > sRxTid) {
                        sRxTid = tid;
                    }
                } else {
                    /* wrap case... */
                    if (sRxTid) {
                        sRxTid = tid;
                    }
                }
                sSemaphore = 1;

                return 1;
            }
        }
        return 0;
    }


    /* Display characters to user */
    void DisplayCharacter(uint8_t array[], char size) {
        _DINT();                                    // Disable interrupts
        //P2SEL |= BIT6 + BIT7;                         // Select P2.6 & P2.7 to UART function

        //UCA0CTL1 |= UCSWRST;                         // **Put state machine in reset**
        //UCA0CTL1 |= UCSSEL_2;                         // SMCLK
        //UCA0BR0 = 18;                                 // 1MHz 57600 (see User's Guide) N = 1MHz/57600
        //UCA0BR1 = 0;                                 // 1MHz 57600
        //UCA0MCTL |= UCBRS_1 + UCBRF_0;                 // Modulation UCBRSx=2, UCBRFx=0
        //UCA0CTL1 &= ~UCSWRST;                         // **Initialize USCI state machine**

        unsigned int i;
        for (i = 0; i < size; i++) {
            while (!(UCA0IFG & UCTXIFG))
                ; // USCI_A0 TX buffer ready?
            UCA0TXBUF = array[i];                 // TX -> RXed character
            _EINT();                            // enable interrupts
        }
    }

    /* Setup UART */
    void initUART(void) {
        PMAPPWD = 0x02D52;                             // Get write-access to port mapping regs
        P2MAP6 = PM_UCA0RXD;                         // Map UCA0RXD output to P2.6
        P2MAP7 = PM_UCA0TXD;                         // Map UCA0TXD output to P2.7
        PMAPPWD = 0;                                 // Lock port mapping registers

        P2DIR |= BIT7;                                 // Set P2.7 as TX output
        P2SEL |= BIT6 + BIT7;                         // Select P2.6 & P2.7 to UART function

        UCA0CTL1 |= UCSWRST;                         // **Put state machine in reset**
        UCA0CTL1 |= UCSSEL_2;                         // SMCLK
        UCA0BR0 = 18;                                 // 1MHz 57600 (see User's Guide) N = 1MHz/57600
        UCA0BR1 = 0;                                 // 1MHz 57600
        UCA0MCTL |= UCBRS_1 + UCBRF_0;                 // Modulation UCBRSx=2, UCBRFx=0
        UCA0CTL1 &= ~UCSWRST;                         // **Initialize USCI state machine**
        UCA0IE |= UCRXIE;                             // Enable USCI_A0 RX interrupt

        _EINT();                                    // Enable interrupts
    }

    //  Interrupt when user inputs data. Set Key_Not_Pressed to 0
    #pragma vector = USCI_A0_VECTOR                // problem !
    __interrupt void USCI_A0_ISR(void) {

        Key_Not_Pressed = 0;

        key = UCA0RXBUF;
        if (key == 0x0D) {
            //we've rx'ed a return, transmit all that's in the buffer
            TxHold = 0;
        }
    }

    ---------------------------------------------------------------------------------------------------------------------------

    While the code compiles and runs fine and the two devices connect it loops at "while ((Key_Not_Pressed))" waiting for user input from RealTerm, it's the same with my main_LinkListen.c code. It appears that my interrupt is not being called when I send bytes. Checking the register values in UCA0STAT it appears I'm getting a USCI Overrun Error flag, a Break received flag and an RX Error flag. I've also tested a simple UART demonstration from the CC430x613x code examples which works fine in its own CSS project but gives the same problem when tested in this project.

    Anybody have any ideas what might be causing this? My suspicion is that it's some kind of interrupt conflict.

    William


    CC430 USCI SimpliciTI UART Interrrupts Interrupt
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 12 2012 07:25 AM
      Guru140650 points

      William Heavin
      static uint8_t key;

      Global variables are always static. However, variables that are changed inside an ISR (or are used to control an ISR) must be declared volatile, so the compiler won't make any assumptions about its content for optimizations.

      A "while (!key);" in main will never exit if key is set in an ISR but the variable isn't devlared volatile. The compiler will read key into a register and test this register over and over again, while the interrupt changes the memory. Using the volatile modifier, the compiler will always read the memory location of key, exactly as often as the code does.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • William Heavin
      Posted by William Heavin
      on Apr 12 2012 08:46 AM
      Prodigy30 points

      You're right, 'key' and also 'Key_Not_Pressed' should be declared volatile, but I'm still getting the same problem. The problem seems to be that the ISR isn't being called in the first place so these values are not being changed regardless. All port settings and the baud rate seem correct.

      However I'm also noticing that USCI_A0_VECTOR seems to be declared in two places, whether this makes a difference or not.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Apr 12 2012 10:57 AM
      Guru140650 points

      William Heavin
      I'm also noticing that USCI_A0_VECTOR seems to be declared in two places, whether this makes a difference or not.

      You only include one of them, and I guess the two files are 100% identical.

      Some people use the "family includes" with oen or more 'x' in the name (for all devices which have same hardware but different ram/flash), some use the generic 'msp430.h' which determines the proper include by the target CPU settings (a dangerous approach, as you do not see form the sourcecode for which MSP the code was written), and some (especially auto-generated code) use individual includes.

      I noticed that you remap the UART pins.
      I dimly remember that some TI library code (so maybe SimpliciTI too) also does remapping, so the port mapping controller is already locked when you try to map your ports. And P2.6 remains CB6 input and P2.7 is CB7 output, and not RX and TX. If so, no wonder that you don't receive anything.
      Do the remapping before initializing SimpliciTI and set the bit that leaves the controller open for further remaps.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use