This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C code forums for MSP430

Other Parts Discussed in Thread: MSP430FR2355

good afternoon....

I was wondering if anyone has input on the best forums out there that can help with code issues with respect to the MSP430 platform?  I am a hardware engineer who has been doing some firmware and I currently am running into a brick wall with respect to eUSCI ISR handling and the strcmp within.

thanks for the response.....

  • I think you found the right place. While we are not a C-tutorial forum, we are certainly glad to help with software issues. 

  • Keith...

    Thank you!....I'm a hardware guy by trait but have been doing firmware lately....I'm struggling with a problem...I want to send a command over the eUSCI, receive the echo back and then send an ACK....It is required for the radio that I am talking to....I prefer NOT to use the software polling (bcz I want to make this very low power) method that TI has in all it's example programs but rather to use hardware IRQ....I am successful at sending out the command AND I see the results (echo) come back to the MSP but for the life of me I cannot capture it correctly.  I am using strcmp.  I have chosen this method because eventually I will evolve the code to handle messages that are NOT always the same length.  I have attached my code and am using a MSP430FR2355....I somehow am missing or so I believe a null character along the way and it is causing the strcmp not to work....Any and all help would be greatly appreciated....Here is my source file....The GPIOs, clock and UART are all working fine the issue is in this piece of work...I just need help getting through the receive part as I'm fully aware the ACK and state 3 may have some issues...My hope was that after I disable the TXIE I can have the RX come through the front door, stay asleep until the rx and tx messages match then wake to continue on in the state machine.  I really look forward to you showing me the error of my ways as I have been struggling with this for days!!

    Thanks a bunch for your reply

    Steve

    /*
     * d_sandbox.c
     *
     *  Created on: Mar 29, 2020
     *      Author: ridge
     */
    
    #include <msp430.h>
    #include <string.h>
    #include "rc.h"
    #include "LPRSradio.h"
    
    volatile char *pRx;// incoming[20];
    const char *pTx, incoming[20] = {0};
    unsigned int sm = 0;
    
    const char *configCmdAck[3] = {r_RSSIon, r_USAFCC, r_bandSet};
    const char* testack = "ACK";
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
        IOconfig;
        initClockTo16MHz();
        initUART();
        pRx = (volatile char*)incoming;
        pTx = configCmdAck[0];
        while (1) {
            __bis_SR_register(LPM3_bits + GIE); //go to sleep: LPM3
            switch (sm)
            {
                case 0: //COMMAND TX
                    sm = 2;
                    break;
                case 1: //ACK TX
                    pTx = configCmdAck[1];
                    sm = 3;
                    break;
                case 2: //ECHO RX
                    pTx = testack;
                    pRx = (volatile char*)incoming;
                    UCA1IE |= UCTXIE;
                    sm = 1;
                    break;
                case 3:  //
                    sm = 0;
                    UCA1IE |= UCTXIE;
                default:
                    break;
            }
    
        }
    }
    
    #pragma vector=USCI_A1_VECTOR
    __interrupt void Payload_RF(void)
    {
        switch(__even_in_range(UCA1IV, USCI_UART_UCTXCPTIFG))
        {
          case USCI_NONE: break;
          case USCI_UART_UCRXIFG:
              *pRx = UCA1RXBUF;
              pRx++;
    
              if (strncmp(pTx, pRx, 10) == 0) {
                  __bic_SR_register_on_exit(LPM3_bits);
              }
    
              break;
          case USCI_UART_UCTXIFG:
    
              if (*pTx == '1') {
                  UCA1IE &= ~UCTXIE;
                  __bic_SR_register_on_exit(LPM3_bits);
              }
    
              UCA1TXBUF = *pTx;
              pTx++;
              break;
          case USCI_UART_UCSTTIFG: break;
          case USCI_UART_UCTXCPTIFG: break;
        }
    }
    

  • ...btw strncmp was an attempt I REALLY want to use strcmp!

    Thanks again

  • ...one more oops....like I said I have been trying things at this end to see if I can understand....

    (*pTx == '\0') instead of the '1' character

  • The strcmp() function requires a properly formed C string which will end with a '\0' character, unless your radio is sending that, you are responsible for adding it. If you are just comparing single characters you can just use (*pTx == '1')

  • r_RSSIon is  a #define "ER_CMD#a01"....I believe the \0 is implied when using double quotes correct?  At least it appears so as the transmit bus is showing the characters ER_CMD#a010 where the last 0 is 0x00......The radio repeats back the same thing on the rx bus yet the strcmp doesn't flag true.....

    On a side note I notice also that I think the correct thing to do in the TXIFG ISR is NOT pTx++ but rather *(pTx++), wouldn't you agree?

    Thanks

  • Hi Steve,

    before I come with more specific recommendations, one probably helpful document is an application report on debugging serial communication with MSP430.

    Sorry for the inconvenience with non optimum code examples, rather showing the non-low power non-realistic polling approach.....

    I'll look deeper into the problem and come back to you with additional recomendations.

    Best regards

    Peter

  • >          if (strncmp(pTx, pRx, 10) == 0) {

    pTx and pRx are moving targets. I suggest something more like:

    >          if (strncmp(testack, incoming, 10) == 0) {

    Since you're not sending the NUL ('\0') byte, you still need to supply it on Rx if you want to use strcmp.

     

  • Trying to run UARTs via hardware IRQ is very difficult.....

    This morning I found two glitches...but still not out of the woods...

    I found that the following with strncmp works:

        k = strlen(configCmdAck[0]);
        test =!(strncmp(pTx, incoming, k));
        if (test) {

  • Peter....

    Thanks.....

    I have an updated version of code which has allowed me to get farther....The following code actually now receives the incoming character and successfully compares it to the prior outgoing character.  I have ended up where I have processed case 2 but then go into LPM3 and don't wake to process case 1 of the state machine to send the ACK....I have tried setting artificially the various TXIFG and TXTCPIFG / TXTCPIE flags but can't seem to get it.....Any ideas?  I can see that the last character of the prior command "ER_CMD#a01" (ie '1') still lingers in the TXBUFFER and the TXIFG flag is not set....My code requires *pTx = null character before it can wake from TXIFG so it doesn't seem to make sense to try and flush that buffer so I thought maybe TXTCP might be the answer......For the record I also found that not having the else in the TX portion of the ISR was causing grief.

    Finally I would like to add to this that I am periodically (depending on the build that I am trying) getting bumped into boot.c to the function CSTART_DECL after I run for the first time.  If I try and reset using CCS debugger, the EVM locks up and wants me to upgrade to the latest FLASH firmware???  I've found that if I hold the EVM reset in while saying UPGRADE, it will reflash then load my application code again.  Once in this state no powering down the board fixes the issue...This is very troubling....

    /*
     * d_sandbox.c
     *
     *  Created on: Mar 29, 2020
     *      Author: ridge
     */
    
    #include <msp430.h>
    #include <string.h>
    #include <stdint.h>
    #include "rc.h"
    #include "LPRSradio.h"
    
    volatile char *pRx, incoming[20];
    const char *pTx;
    unsigned int sm = 0;
    const char *configCmdAck[] = {r_RSSIon, r_USAFCC, r_bandSet};
    const char *testack = "ACK";
    int test = 0, i = 0, k;
    
    
    int main(void)
    
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
        IOconfig;
        initClockTo16MHz();
        initUART();
        pRx = incoming;
        pTx = configCmdAck[0];
        k = strlen(configCmdAck[0]);
    
        while (1) {
            __bis_SR_register(LPM3_bits + GIE); //go to sleep: LPM3
            switch (sm)
            {
                case 0: //COMMAND TX:  processed AFTER transmitting first char string
                    pTx = configCmdAck[i];
                    sm = 2;
                    break;
                case 1: //ACK TX
                    pTx = testack;
                    UCA1IFG |= UCTXIFG;
                    sm = 3;
                    break;
                case 2: //ECHO RX
                    pRx = incoming;
                    i++;
                    sm = 1;
                    UCA1IE |= UCTXCPTIE;
                    break;
                case 3:  //
                    sm = 0;
                    UCA1IE |= UCTXIE;
                    break;
                default:
                    break;
            }
        }
    }
    
    #pragma vector=USCI_A1_VECTOR
    __interrupt void Payload_RF(void)
    {
        switch(__even_in_range(UCA1IV, USCI_UART_UCTXCPTIFG))
        {
          case USCI_NONE: break;
          case USCI_UART_UCRXIFG:
              *pRx = UCA1RXBUF;
              pRx++;
              test =!(strncmp(pTx, incoming, k));
              if (test) {
                  __bic_SR_register_on_exit(LPM3_bits);
              }
    
              break;
          case USCI_UART_UCTXIFG:
              if (*pTx == '\0') {
                  __bic_SR_register_on_exit(LPM3_bits);
              }
              else {
                  UCA1TXBUF = *pTx;
                  *(pTx++);
              }
              break;
          case USCI_UART_UCSTTIFG: break;
          case USCI_UART_UCTXCPTIFG:
              __bic_SR_register_on_exit(LPM3_bits);
              break;
        }
    }
    

  • Hi Steve,

    many thanks for the update. On the troubles with FW upgrade requests and so on. I am not sure, but we see from time to time with these smaller FRAM devices, which are limited on HW breakpoints, the SW breakpoints causing trouble, like resets and jumping into the weeds. Now please don't assume SW breakpoints are only set by you. E.g. halting the CPU at the 1st code line of main after reset or download, or other break points could be set by CCS as SW breakpoints due to the HW breakpoints limitations. What you could do is trying to disable the use of SW breakpoints. You can find this in the project properties and .... please see below screen shot.

    The other point might be overclocking the device. Please keep in mind the specification on wait cycles in case you run the device at higher speed than 8MHz.

    I'll need to think your code through a bit more in detail. Unfortunately I am based in Germany and we're close to end of business and due to Easter public holiday I'll return only by Tuesday next week. Sorry for that.

    It would be good to be able reproducing this on my side, but I am lacking the counterpart, you're using, so if you see an chance, recreating this on your side using another MSP430, it would make it easier.

    Best regards

    Peter

  • Hi Steve,

    please let us know, whether you still need support on this one. Many thanks in advance.

    Best regards

    Peter

**Attention** This is a public forum