Why does U0RBR only return 1 char at a time ?

Here’s the issue I’m having.

I receive data from a device to my lpc2378 chip and then re-echo it back to my pc to verify the data that I’ve received is correct.

The data that I receive is “112233” which to me is 3 bytes of data. Unfortunately it only seems to get “112” which is 3 chars to me.

What I’m trying to do is fairly clear here but for what ever reason it only seems to grab 3 chars at a time when it should be 6 chars.

I’m using interrupts and a custom function for grabbing the data from the buffer.

int uart0GetByte(void)
{
#ifdef UART0_RX_INT_MODE
	  unsigned cpsr;
	  int ch;

	  if (uart0_rx_insert_idx == uart0_rx_extract_idx) // check if character is available
		  return -1;

	  cpsr = disableIRQ();                  // disable global interrupts
	  restoreIRQ(cpsr);                     // restore global interrupts

	  ch = uart0_rx_buffer[uart0_rx_extract_idx++]; // get character, bump pointer
	  uart0_rx_extract_idx %= UART0_RX_BUFFER_SIZE; // limit the pointer

	  return ch;
	#else
	  if (U0LSR & ULSR_RDR)                 // check if character is available
		  ch = U0RBR;
	    return ch;                       // return character

	  return -1;
	#endif
}

int* uart0Read(void)
{
	static int rx_data[255];
	int byte;
	int rx_size = 0;

	// Get Rest of Bytes
	do {
		if ((byte = uart0GetByte()) >=0) {
			rx_data[rx_size++] = byte;
		}
	} while (rx_size != 3);

	return rx_data;
}

const int *uart0Putb(const int *string)
{
  register int ch;

  while ((ch = *string) && (uart0Putch(ch) >= 0))
    string++;

  return string;
}

void uart0ISR(void)
{
  uint8_t iid;

  // perform proper ISR entry so thumb-interwork works properly
  ISR_ENTRY();

  // loop until not more interrupt sources
  while (((iid = U0IIR) & UIIR_NO_INT) == 0)
    {
    // identify & process the highest priority interrupt
    switch (iid & UIIR_ID_MASK)
      {
      case UIIR_RLS_INT:                // Receive Line Status
        U0LSR;                          // read LSR to clear
        break;

#ifdef UART0_RX_INT_MODE
      case UIIR_CTI_INT:                // Character Timeout Indicator
      case UIIR_RDA_INT:                // Receive Data Available
      do
          {
          uint16_t temp;

          // calc next insert index & store character
          temp = (uart0_rx_insert_idx + 1) % UART0_RX_BUFFER_SIZE;
          uart0_rx_buffer[uart0_rx_insert_idx] = U0RBR;

          // check for more room in queue
          if (temp != uart0_rx_extract_idx)
            uart0_rx_insert_idx = temp; // update insert index
          }

        while (U0LSR & ULSR_RDR);

        break;
#endif

#ifdef UART0_TX_INT_MODE
      case UIIR_THRE_INT:               // Transmit Holding Register Empty
        while (U0LSR & ULSR_THRE)
          {
          // check if more data to send
          if (uart0_tx_insert_idx != uart0_tx_extract_idx)
            {
            U0THR = uart0_tx_buffer[uart0_tx_extract_idx++];
            uart0_tx_extract_idx %= UART0_TX_BUFFER_SIZE;
            }
          else
            {
            // no
            uart0_tx_running = 0;       // clear running flag
            break;
            }
          }

        break;
#endif // UART0_TX_INT_MODE

      default:                          // Unknown
        U0LSR;
        U0RBR;
        break;
      }
    }

  VICVectAddr = 0x00000000;             // clear this interrupt from the VIC
  ISR_EXIT();                           // recover registers and return
}
#endif // defined(UART0_TX_INT_MODE) || defined(UART0_RX_INT_MODE)
#endif // UART0_SUPPORT

Any reason why the above code returns chars and not bytes and what would be the solution to this ?

You seem to be very confused about bytes and chars. Both are 8 bits. Looking at your code and your statements, it seems like you think a 16 bit int is a byte. On older chips, an int was 16 bits, but on an Arm it is 32 bits. A byte and char will always be 8 bits. It would seem to me that you are dealing with 6 bytes of data.

Andy

ok so if “112233” is actually 6 bytes of data and NOT 3 bytes like I was thinking then how would I compare for 33 in that data string ?

Use a loop to search the array for ‘3’, then check the following byte for ‘3’. You could use the “index” function in the strings library for the search. Function “strstr” does the whole thing.

Leon

well byte 5 and 6 won’t always be 33 and I always look at them together so if it was byte 5 being 1 and byte 6 being 8 I need to see it as 18 together.

i know this was much simpler in vb.net and now going to c++ seems to have confused me somewhat.

be nice if I could say take data “112233445566” and put that into an array to go through.

in vb.net using serialport 2 chars repersents 1 byte hence why i’m confused right now.

It doesn’t matter what they are. Just find the first byte in the string and then check the next one as I suggested. Or use strstr. It’s standard C.

Leon

echel0n:
i know this was much simpler in vb.net and now going to c++ seems to have confused me somewhat.

Well I did try to warn you. You are still only a couple of weeks into your 'few months' learning experience so you should expect to have to jump a few more hurdles yet :-(

in vb.net using serialport 2 chars repersents 1 byte hence why i’m confused right now.

Are you confusing hexadecimal digits with alphabetic chars perhaps?

Think about it: A byte is generally considered to be an eight bit quantity. If you could fit 2 chars into one byte then each char would be four bits. Four bits only allows you to represent 16 different values which would be a very restricted character set.

ok yes I understand now what your saying. is it possible to do double-byte char arrays ?

char array = {‘A’, ‘B’};

is an example of a two byte char array.

array[0] = ‘A’ and array[1] = ‘B’

Leon

can I do this?

char array = {‘11’,‘22’,‘33’} ?

if so then how can I insert data into a char array like that repersented above ?

sorry if this sounds like dumb questions but just trying to learn and get a project done. i’m used to doing things by trial and error and rarely like asking questions but really going from vb.net to c++ seems to be really throwing me for a loop so to speak.

also other includes such as string.h I notice don’t exist initally, do I have to download those files or ?

I guess what I’m asking for is how to create a 2D char array from serial rx data.

That won’t work, ‘11’ isn’t valid C.

You’d have to use

char array = {‘1’, ‘1’, ‘2’, ‘2’, ‘3’, ‘3’};

or define it as a string. You’ll have a 0 terminating byte in the string array, of course, which might cause problems.

Leon

Say I do this:

byte1 = array[0];

byte2 = array[1];

how would I join those together to make “11” ??

Calculate byte1*10 + byte2 and convert to a string with itoa.

You ought to get a copy of K&R, The C programming Language. All this stuff is in there.

Leon

You know I’ve been completely thinking backwards and shit on this since i’m trying to switch myself into c++ from vb.net.

Char would be ascii rep of hex so I shouldn’t be storing these values into char is my guess.

Probally should be using INT or SHORT to store the hex values or converting from char to int to get what I wanted.

I’ve been assuming this whole time that data is sent like “112233” but realistically it’s not that way and I’ve just been making things alot harder then they needed to me.

Anyways I thank you for the advise and help and will most defenityly seek out a book on c programming.