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.

Problems in UART communication.

Other Parts Discussed in Thread: CC2541

Hi

I am using the CC2541 in my application and I am facing some problems in UART communication. Here is the issue which I am facing.

I am using the 2400 baud-rate, even parity, one start, one stop bit configuration. Everything seems fine but sometimes I am facing the parity error in transmission. My oscilloscope is showing that there is an parity error in transmission and using serial port sniffer I am able to see that command I am sending is being corrupted sometimes(For ex. one time I observed that I sent 0X02 but sniffer was showing 0x06).

Any idea that what I am missing or what causes this parity error?

Thanks,

Maulik.

  • Hi Maulik,

    How are you setting up the UART? Manually, or via a HAL driver in the stack?

    If your oscilloscope shows that the byte is indeed 0x06 when it should have been 0x02 something is obviously wrong. How easy is it to reproduce this? Could it be that the wrong value is sent to the UART register?

    Best regards;
    Aslak 

  • Hi Aslak,

    We are using our independent UART ISR  rather than HAL driver in stack. We are sending 0x02 command on UART transmitter when Pairing and Bonding is enable.

    In our case, When Pairing and Bonding Successful callback call, we are sending 0x02 and  sometimes we are facing parity error.

    Regards,

    Maulik Patel

  • Hi Maulik,

    This isn't really a lot of information to go on, I'm afraid, as I don't know your ISR routine.

    It could be a problem if the device goes to sleep or something while you are sending stuff. Try to either disable the POWER_SAVING define in the project options by renaming it to xPOWER_SAVING, or make a call to osal_pwrmgr_device( PWRMGR_ALWAYS_ON ); when you want to send and when you are finished, call with PWRMGR_BATTERY as argument.

    Best regards,
    Aslak 

  • Hi Aslak,

    We are using POWER_SAVING is enable. But when we want to send data on UART, we are setting POWER HOLD state by  osal_pwrmgr_task_state(TaskID, PWRMGR_HOLD);  and after completion we set POWER CONVERSE by  osal_pwrmgr_task_state(TaskID, PWRMGR_HOLD);  So there is no issue of power saving and holding.

    Regards,

    Dhvani Patel

  • Hi Aslak ,

    We are performing following things in UART tx ISR ,

    When UART TX ISR  called , we set timer3 for 40ms,  GPIO pin P1.6 to low and exit from ISR, after 40ms delay we put data in U0DBUF and UART TX ISR is called again and we set timer3 for 12ms delay and exit after 12ms we set GPIO pin P1.6 to high.

    Regards,

    Dhvani Patel

  • Try setting UxBAUD.BAUD_M to 58 & 60; try a different baud rate - how about 115.2?

     

  • Hi Harry,

    In our application, We are using 2400 baud rate not 115200 and setting UxBAUD.BAUD_M to 59 and  UxGCR.BAUD_E to 6 for 2400 baud rate.

    Regards,

    Dhvani Patel

  • Hi

    Can anyone suggest me why i am getting parity error. So on sniffer i am getting wrong command on UART packet sniffer. Here i am posting UART transmitter code.

    Here Before we put actual data transfer on UART  UODBUF, We put delay 40 ms. Please provide me some help if i am doing some wrong things.

    #define SEND_IDLE    0
    #define START_DELAY  1
    #define SEND         2
    #define STOP_DELAY   3

    uint8 Buffer[128];
    uint8 Tail=0;
    volatile uint8 Head=0;
    uint8 Delay = 0;    // in turms of ms
    volatile uint8 flag = false;
    volatile uint8 State = UART_SEND_IDLE;  // uart tx state flag


    // an app function to write command in buffer for transmitt and exit

    uint8 writeUARTCmd( uint8 cmd )
    {
      Buffer[Tail] = cmd;
     
      if (Tail >= 128)
      {
        Tail = 0;
      }
      else
      {
        Tail++;
      }

      if(flag == false )   // if command on uart not seding set intr.
      {
        IEN2 |= UTX0IE;
      }
      osal_pwrmgr_task_state(TaskID, PWRMGR_HOLD);
      return SUCCESS;
    }


    // function set timer3 for delay.
    void timer3(uint16 msdelay)
    {
      Delay = msdelay;
      start timer3 for msdelay.
    }


    // UART0 tx ISR .
    // First check is any data to send on UART  by checking Head and Tail
    // If no data to send then disable UART tx intrrupt and set power in converse state.
    // If there is data to send on UART
    // clear IF,  start TIMER 3 to 40 ms delay before actully data to put on UART U0DBUF register.
    // Exit.

    HAL_ISR_FUNCTION( halUART0TxIsr, UTX0_VECTOR )
    {
      if(Head == Tail)
      {
        IEN2 &= ~UTX0IE;
        osal_pwrmgr_task_state(TaskID, PWRMGR_CONSERVE);
      }

      else
      {
        if(flag == false )
        {
          flag = true;
          UTX0IF = 0;
          if(State == UART_SEND_IDLE )  // check UART state IDLE
          {
            State = UART_START_DELAY;  // state change to START_DELAY
            timer3(40); // Start timer3 for delay
          }
        }
      }
    }



    // Timer 3 ISR is called every 1ms second
    // Decrement Delay counter
    // if Delay counter is zero.
    // if UART state is UART_START_DELAY then call UARTSendCmd()
    // else if state is UART_STOP_DELAY  then call UARTSendComplete()
    HAL_ISR_FUNCTION( halTimer3Isr, T3_VECTOR )
    {
      TIMIF &=  0xFE ;        // cler timer3 flag;
      T3CTL &= ~0x10;          //stop timer
      Delay--;
      if(Delay <= 0) {
        T3CTL |= 0x04;
        if(State == UART_START_DELAY ) {
          UARTSendCmd();
        }
        else if (State == UART_STOP_DELAY) {
          UARTSendComplete();
        }

      }
      else {
        T3CTL |= 0x10;       // start timer
      }
    }


    // Function put Data on UODBIF from local Buffer
    // And start timer3 for 12ms delay
    // Put state to UART_SEND
    void UARTSendCmd()
    {
     
      UTX0IF = 0;
      U0DBUF = txBuffer[uartTxHead];
      IEN2 &= ~UTX0IE;  
      State = UART_SEND;
      timer3(12);
    }


    // Funcrion called 12ms delay
    // set UART state to idle
    // Enable UART tx interrupt and set interrupt flag true
    // So UART tx interrupt called again.
    void UARTSendComplete()
    {
      Head++;
      if(Head >= 128)
      {
        Head = 0;
      }
      State = UART_SEND_IDLE;
      flag = false;
      IEN2 |= UTX0IE;
      UTX0IF = 1;
    }

    Waiting for response,

    Thanks in advanced,

    Dhvani Patel