c++arduino-dueatsam3x

Comparing an usart received uint8_t* data with a constant string


I'm working on an Arduino Due, trying to use DMA functions as I'm working on a project where speed is critical. I found the following function to receive through serial:

uint8_t DmaSerial::get(uint8_t* bytes, uint8_t length) { 

// Disable receive PDC
uart->UART_PTCR = UART_PTCR_RXTDIS;

// Wait for PDC disable to take effect
while (uart->UART_PTSR & UART_PTSR_RXTEN);

// Modulus needed if RNCR is zero and RPR counts to end of buffer
rx_tail = (uart->UART_RPR - (uint32_t)rx_buffer) % DMA_SERIAL_RX_BUFFER_LENGTH;

// Make sure RPR follows (actually only needed if RRP is counted to the end of buffer and RNCR is zero)
uart->UART_RPR = (uint32_t)rx_buffer + rx_tail;

// Update fill counter
rx_count = DMA_SERIAL_RX_BUFFER_LENGTH - uart->UART_RCR - uart->UART_RNCR;

// No bytes in buffer to retrieve
if (rx_count == 0) { uart->UART_PTCR = UART_PTCR_RXTEN; return 0; } 

uint8_t i = 0;

while (length--) {

    bytes[i++] = rx_buffer[rx_head];

    // If buffer is wrapped, increment RNCR, else just increment the RCR
    if (rx_tail > rx_head) { uart->UART_RNCR++; } else { uart->UART_RCR++; }    

    // Increment head and account for wrap around
    rx_head = (rx_head + 1) % DMA_SERIAL_RX_BUFFER_LENGTH;

    // Decrement counter keeping track of amount data in buffer
    rx_count--;

    // Buffer is empty
    if (rx_count == 0) { break; }
}

// Turn on receiver
uart->UART_PTCR = UART_PTCR_RXTEN;

return i; 
}

So, as far as I understand, this function writes to the variable bytes, as a pointer, what is received as long as is no longer than length. So I'm calling it this way:

 dma_serial1.get(data, 8);

without assigning its returning value to a variable. I'm thinking the received value is stored to the uint8_t* data but I might be wrong.

Finally, what I want to do is to check if the received data is a certain char to take decisions, like this:

if (data == "t"){
//do something//}

How could I make this work?


Solution

  • For comparing strings like intended by if (data == "t"), you'll need a string comparison function like, for example, strcmp. For this to work, you must ensure that the arguments are actually (0-terminated) C-strings:

    uint8_t data[9];
    uint8_t size = dma_serial1.get(data, 8);
    data[size]='\0';
    if (strcmp(data,"t")==0) {
       ...
    }
    

    In case that the default character type in your environment is signed char, to pass data directly to string functions, a cast is needed from unsigned to signed:

    if (strcmp(reinterpret_cast<const char*>(data),"t")==0) {
       ...
    }
    

    So a complete MVCE could look as follows:

    int get(uint8_t *data, int size) {
        data[0] = 't';
        return 1;
    }
    
    int main()
    {
        uint8_t data[9];
        uint8_t size = get(data, 8);
        data[size]='\0';
        if (strcmp(reinterpret_cast<const char*>(data),"t")==0) {
            cout << "found 't'" << endl;
        }
    }
    

    Output:

    found 't'