• AVR Freaks

Hot!Harmony v2 usart driver buffer size?

Author
dreamstar1
New Member
  • Total Posts : 3
  • Reward points : 0
  • Joined: 2020/03/11 02:46:50
  • Location: 0
  • Status: offline
2020/04/16 22:35:39 (permalink)
0

Harmony v2 usart driver buffer size?

Sorry I'm really new to embedded programming, so bear with me with my dumb questions.
I'm using pic32mx470f512L with Harmony 2 and dynamic USART driver with byte model support and non-interrupt mode.
I've noticed that if i were to send multiple commands or long commands from the pc with rs232, the chip would be irresponsive due to the small buffer size. ex)read31+read30+
I'm using + as a terminate charc.
When i call DRV_USART_ReceiverBufferSizeGet(handle) it returns 8 byte. 
So it seems receiving more than 8 charc at once would cause issue.
For transmission if i were to send more than 8 charc back, it causes issues as well.
 
1) How do i increase the buffer size for receive and transmit? I dont see any option in the harmony configurator window.
2) I've seen mention of circular buffer that may fix this issue? Is there an example of how to implement this with the auto generated code from harmony configurator?
 
 
typedef struct {
        /* The application's current state */
        APP_STATES state;
        char buf[30];
        DRV_HANDLE usartHandle;
        char rx;
        /* TODO: Define any additional data used by the application. */

    } APP_DATA;

 

void APP_Initialize(void) {
    /* Place the App state machine in its initial state. */
    appData.state = APP_STATE_INIT;
    appData.usartHandle = DRV_USART_Open(DRV_USART_INDEX_0, DRV_IO_INTENT_READWRITE);
}

void APP_Tasks(void) {
    /* Check the application's current state. */
    switch (appData.state) {
            /* Application's initial state. */
        case APP_STATE_INIT:
        {
            bool appInitialized = true;
            if (appInitialized) {
                appData.state = APP_STATE_IDLE;
            }
            break;
        }

        case APP_STATE_IDLE:
        {
            if (!DRV_USART_ReceiverBufferIsEmpty(appData.usartHandle)) {
                appData.rx = DRV_USART_ReadByte(appData.usartHandle);
                if (appData.rx != '+') {
                    appData.buf[i] = appData.rx;
                    i++;
                } else { //example) read30+ sent from pc
                    if (strstr(appData.buf, "read") != NULL) {
                        char extractedInt[3] = {appData.buf[i - 2], appData.buf[i - 1], '\n'};
                        char *leftoverString;
                        adcPin = (int) strtol(extractedInt, &leftoverString, 10); //gets the number 30 
                        writeInt(adcPin); //transmit 30
                        writeInputString("p"); //transmit p
                        writeInt(sensorCount(adcPin)); //transmit 61000
                        DRV_USART_WriteByte(appData.usartHandle, '\n'); \\ transmit /n to notify pc transmit ends

                    } else {
                        appData.state = APP_STATE_WRITE;
                    }
                    appData.buf[i] = 0;
                    i = 0;
                }
            }
            break;
        }

        case APP_STATE_WRITE:
        {
            writeInputString(appData.buf);
            DRV_USART_WriteByte(appData.usartHandle, '\n');
            appData.state = APP_STATE_IDLE;
            break;
        }
            /* The default state should never be executed. */
        default:
        {
            /* TODO: Handle error in application's state machine. */
            break;
        }
    }
}

void writeInt(uint16_t num) {
    char tmp[17]; //size of uint16_t is too small for some reason
    snprintf(tmp, sizeof tmp, "%d", num);
    writeInputString(tmp);
}
 
void writeInputString(char buffer[]) {
    char* inputStr = buffer;
    while (*inputStr) {
        if (!(DRV_USART_TRANSFER_STATUS_TRANSMIT_FULL & DRV_USART_TransferStatus(appData.usartHandle))) {
        DRV_USART_WriteByte(appData.usartHandle, *inputStr++);
        }
    }
}

 
#1
arpananand
Super Member
  • Total Posts : 498
  • Reward points : 0
  • Joined: 2009/11/18 04:35:42
  • Location: 0
  • Status: offline
Re: Harmony v2 usart driver buffer size? 2020/04/17 03:30:46 (permalink)
0
if you are looking to transfer longer data, then you may want to consider buffer queue model. check harmony help doc for usart driver, that has examples of all the models usage.
 
#2
Paul PortSol
Super Member
  • Total Posts : 636
  • Reward points : 0
  • Joined: 2015/07/03 11:52:03
  • Location: Newfoundland, Canada
  • Status: offline
Re: Harmony v2 usart driver buffer size? 2020/04/17 05:39:39 (permalink)
0
You can also create your own "ring buffer" code (see https://en.wikipedia.org/wiki/Circular_buffer).
 
If use ringbuffers I would recommend you use Interrupt receive to the ring buffer, it ensure receive continues when code may be otherwise busy.
Also note that most PICs have a FIFO on UART Tx/Rx, so handle filling/emptying available FIFO space during Tx/Rx. Use largest FIFO to minimize "code overhead" (CPU time lost in interrupts, etc.).
 
For Tx it is fine to write to ring buffer, but only output from ring to port once per task cycle (not use Tx Interrupt, that way you don't have to handle reenabling Tx interrupt after an interrupt with no tx data). If you are doing very high baudrate and need maximum throughput then you may need Tx Interrupt, but for most UART stuff with a fast MCU that shouldn't be necessary.
 
With ring buffers you have to decide which is more important: new data, old data, or just flagging an overflow.
If buffer overflows (no space to add more data) then set a flag (part of ring structure). Then once a task cycle check the flag, and if overflow occurred appropriately (for your project) display something, log something, reset the buffer contents(discard), enlarge buffer size (runtime or code change), or change code so timing ensures never overflow again (slow baud rate, add limit/delay in messaging, shorten packets, etc.).
 
Personally I use Byte mode with receive interrupts, my own ring buffer code on Tx and Rx. That gives me very transportable code to other projects/hardware.
 
Paul
 
#3
dreamstar1
New Member
  • Total Posts : 3
  • Reward points : 0
  • Joined: 2020/03/11 02:46:50
  • Location: 0
  • Status: offline
Re: Harmony v2 usart driver buffer size? 2020/04/17 22:59:15 (permalink)
0
Is there no way to simply increase the buffer size for byte model support through harmony?
Circular buffer seems a bit complicated to implement for rx and tx.
#4
NKurzman
A Guy on the Net
  • Total Posts : 19026
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: Harmony v2 usart driver buffer size? 2020/04/17 23:13:46 (permalink)
0
If the driver is using the Hardware buffer of The UART, then no it can not be changed.
Harmony 1and two do not offer the normal ring buffer that everyone (including the MCC group) uses for a a Serial Port.
Your options are the buffer queue.
The ring buffer.
Or if your apply application can handle it a linear buffer. You fill the buffer and use that to feed the UART. Using the harmony driver, we’re handling UART registers directly.
This method means you can only send one message or receive one message at a time.
It is less flexible but easier to implement.

If you want working ring buffer code your can build an MCC project t for a PIC24 or a small PIC32. Steal the ring buffer code and poured it to Your Harmony project.

Those would be your common choices.
#5
Jump to:
© 2020 APG vNext Commercial Version 4.5