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.

UART how do we know when to stop receiving bytes?

Other Parts Discussed in Thread: MSP430F5529

Hi

I am using the MSP430F5529 Launchpad, interfaced with an OBD-II UART (https://www.sparkfun.com/products/9555) module in vehicles. 

The uart is interrupt driven, and my question is how do we know when to disable the receive interrupt if the amount of bytes coming from the vehicles OBD isn't known?

#include "msp430x552x.h"
#include "delay.h"
#include <stdlib.h>
#include <stdio.h>


unsigned int _rxCounter;
//char tx[];
char rx[];

unsigned char *transmit;
unsigned char currChar;
unsigned char charCount;

void UART_transmit(unsigned char *cmd, unsigned char count);

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  //P1DIR |= 0x1;
  //P4DIR |= 0x8;


  P3SEL |= BIT3+BIT4;                       // P3.3,4 = USCI_A0 TXD/RXD
  P3REN |= BIT3 + BIT4;
  UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 208;                              // 1MHz  (see User's Guide)
  UCA0BR1 = 0;                              // 1MHz 115200
  UCA0MCTL |= UCBRS_1 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  //UCA0IE |= UCRXIE;                       // Enable USCI_A0 RX interrupt

  __enable_interrupt();

  UART_transmit("ATZ", 3);
  _rxCounter = 0;
  UART_transmit("ATRV", 4);
  UART_receive();

  while(1);

  //__bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
  //__no_operation();                         // For debugger
}

void UART_transmit(unsigned char *cmd, unsigned char count)
{
	transmit = cmd;
	charCount = count;

	UCA0IE |= UCTXIE;

	 //__bis_SR_register(LPM0_bits + GIE);
	 //__no_operation();

}

void UART_receive(void){
	UCA0IE |= UCRXIE;
	//__bis_SR_register(LPM0_bits + GIE);
	__no_operation();

}

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
	switch(__even_in_range(UCA0IV,4)){
	case 0:break;
	case 2:
		rx[_rxCounter++] = UCA0RXBUF;
		break;
	case 4:
		if(charCount) {
			UCA0TXBUF = *transmit++;
			charCount--;
		}
		else {
			UCA0IFG &= ~UCTXIFG;
			//__bic_SR_register_on_exit(LPM0_bits);
		}
		break;
	default: break;
	}
}

  • I asked the same question for CC430. They seem to have same port.. So, you cannot.. It only has RX and TX irq, no status change IRQ..


    You may not need to disable IRQ.. Just handle incoming bytes, if you're not using them, just drop.. If you disable, how do you know when it starts? IDLE period, enable after TX?

  • It is an inherent ‘feature’ of an UART (the key letter is the ‘A’ which means ‘asynchronous’) that you can’t know whether and when more data is coming, unless it happens, or the data you already got tells you it won’t happen (like a ‘package size’ counter).

    You can implement a timeout. E.g. use the watchdog in counter mode and reset it on every RX interrupt. When the watchdog expires, you know that you didn’t get data for a certain time and you can act accordingly.

  • Dilan de Silva said:
    The uart is interrupt driven, and my question is how do we know when to disable the receive interrupt if the amount of bytes coming from the vehicles OBD isn't known?

    The answer is to know how many bytes to expect. You typically would implement a multi-layer stack like this:

    Application Layer
    -----------------------
    OBD-II Protocol Handler
    -----------------------
    ELM327 Protocol Handler
    -----------------------
    Low-Level UART Driver
    -----------------------
    MSP430 Hardware UART

     
    Your application would send/receive data through the stack, and each layer knows how to decode it's own piece of the puzzle. You don't operate on bytes, but on messages.

**Attention** This is a public forum