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.

MSP430FR5994: SoftUart

Part Number: MSP430FR5994


Good afternoon community!

Someone already worked SoftUart? I need help. I am implementing a SoftUart at 115200Hz on a MSP430FR5994 microcontroller at 8MHz. with TXD at P4.1 and RXD at P4.2. 
It already sends string but at the time of receiving it only receives 1s.  I appreciate your help.

Below is my code..

// main.c -------------------------------------------

#include <msp430.h>
#include <stdint.h>
#include "uart.h"

int main(void)
{     
      // stop watchdog timer
      WDTCTL = WDTPW + WDTHOLD;            // Stop WDT
      SetClockMHz();
      ConfigurePORTS();
      PM5CTL0 &= ~LOCKLPM5;                        // Disable the GPIO power-on
      __enable_interrupt();                                    // Enable Global Interrupts

      uart_puts(" MSP430 SoftUart 115200\n\r");

      while (1)
      {
            if (uart_getc(&Data)) {
                  uart_putc(Data);
                  __delay_cycles(4000000);
            }
      }
}

// uart.h --------------------------------------------

#ifndef __UART_H
#define __UART_H

#include <stdbool.h>
#include <stdint.h>

# define TXD BIT1                                             // TXD em P4.1
# define RXD BIT2                                            // RXD em P4.2
# define F8MHz 8000000                                  // CPU 8MHz
# define BAUDRATE 115200                             // Taxa de transmissão
# define BIT_TIME (F8MHz/BAUDRATE)         // Tempo de bits
# define HALF_BIT_TIME (BIT_TIME/2)           // Tempo de meio bit
static volatile uint8_t bitCount=0;                       // Contagem de bits
static unsigned int TXByte;                                // Valor enviado por uart_putc()
static unsigned int RXByte;                                // Valor recebido
static bool isReceiving = false ;                         // Status dispositivo
static bool hasReceived = false ;                       // um byte é recebido

/* Initialize soft UART */
void SetClockMHz (void);
void ConfigurePORTS (void);
bool uart_getc(uint8_t *c);
void uart_putc(uint8_t c);
void uart_puts(const char *str);

#endif /* UART_H_ */

// uart.c ----------------------------------------

#include <msp430.h>
#include <stdbool.h>
#include "uart.h"

/* Initialize soft UART */
void SetClockMHz (void)
{
      // Startup clock system with DCO ~8MHz
      CSCTL0 = CSKEY;                                       // Unlock CS registers
      CSCTL1 = DCOFSEL_6;                              // Set DCO to 8MHz
      CSCTL2 = SELA__VLOCLK|SELS__DCOCLK|SELM__DCOCLK;
      CSCTL3 = DIVA__1|DIVS__1|DIVM__1;     // Set all dividers
      CSCTL0_H = 0;                                            // Lock CS Registers
      return;
}

void ConfigurePORTS(void)
{
      // Configure TXD
      P4DIR |= TXD;             // P4.1 TX Output

      // Configure RXD
      P4DIR &= ~RXD;       // P4.2 RX Input
      P4OUT |= RXD;         // Set internal pull-up resistor
      P4REN |= RXD;         // Enable internal Pull-Up Resistors
      P4IES |= RXD;          // High-to-low transition
      P4IFG &= ~RXD;       // Clear Interrupt Flag
      P4IE |= RXD;             // Interrupt Enable
      return;
}

/* Read one character from UART non-blocking.*/
bool uart_getc(uint8_t *c)
{
      if (!hasReceived) { return false; }
      *c = RXByte;
      hasReceived = false;
      return true;
}

/* Write one chracter to the UART blocking */
void uart_putc(uint8_t c)
{
      TXByte = c;
      while(isReceiving);                                                // Wait for RX completion

      bitCount = 0xA;                                                     // Load Bit counter, Start + 8 bits + Stop
      TXByte |= 0x100;                                                  // Add STOP bit to TXByte
      TXByte = TXByte << 1;                                         // Add START bit 0

      TA0CTL = TASSEL__SMCLK + MC__CONTINOUS; // SMCLK/1 + Continuous Mode
      TA0CCR0 = TA0R;                                                // Get current timer count
      TA0CCR0 += BIT_TIME;                                       // Add Offset to TA0CCR0
      TA0CCTL0 = CCIS_0 + OUTMOD_0 + CCIE + OUT; // Set signal, Enable Interrupts
      while (TA0CCTL0 & CCIE);                                   // Wait for previous TX completion
      return;
}

/* Write string to the UART blocking. */
void uart_puts(const char *str) {
      if(*str != 0) uart_putc(*str++);
      while(*str != 0) uart_putc(*str++);
      return;
}

/* ISR for PORT4 */
#pragma vector = PORT4_VECTOR
__interrupt void PORT4_ISR(void)
{
      isReceiving = true;
      P4IE &= ~RXD;                                                  // Disable Interrupt P4.2
      P4IFG &= ~RXD;                                               // Clear Interrupt Flag P4.2

      TA0CTL = TASSEL__SMCLK + MC__CONTINOUS; // SMCLK + Continuous Mode
      TA0CCR0 = TA0R;                                            // Initialize TA0CCR0
      TA0CCR0 += HALF_BIT_TIME;                       // Add Offset to TA0CCR0
      TA0CCTL0 = OUTMOD_1 + CCIE;                  // Disable TX and enable interrupt Timer

      RXByte = 0x00;                                                // Initialize RXByte
      bitCount = 0x9;                                                 // Load bitCounter, 8 bits + 1 start
}

/* CCR0 ISR for TXD and RXD */
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR (void)
{
      TA0CCR0 += BIT_TIME;                                  // Add Offset to TA0CCR0
      if(!isReceiving) {                                                // Transmiting
            if ( bitCount == 0) {                                      // Finish?
            TA0CTL = TASSEL__SMCLK;                    // TASSEL_SMCLK, timer off
            TA0CCTL0 &= ~CCIE;                                // Disable interrupt Timer
            }
            else {
                  if (TXByte & 0x01) { P4OUT |= TXD; }  // P4.1 = 1
                  else { P4OUT &= ~TXD; }                     // P4.1 = 0
                  TXByte >>= 1;
                  bitCount --;
                  }
      }
      else {                                                                 // Receiving
            if ( bitCount == 0) {                                      // Finish?
                  TA0CTL = TASSEL__SMCLK;              // SMCLK, timer off
                  TA0CCTL0 &= ~CCIE ;                         // Disable Interrupt Timer
                  P4IE |= RXD;                                         // Interrupt Enable P4.2
                  isReceiving = false;
                  if ((RXByte & 0x201) == 0x200) {         // Validate the start and stop bit
                        RXByte >>= 1;                                // Remove start bit
                        RXByte &= 0xFF;                            // Remove stop bit
                        hasReceived = true;
                  }
            }
            else {
            if (P4IN & RXD) { RXByte |= 0x400; }         // If bit is set?
                  RXByte >>= 1;                                      // Shift the bits down
                  bitCount --;
            }
      }
}

**Attention** This is a public forum