• AVR Freaks

Hot!PIC32MX UART flow control not working in block transfers

Author
dr_lewis
New Member
  • Total Posts : 10
  • Reward points : 0
  • Joined: 2016/01/21 06:57:22
  • Location: 0
  • Status: offline
2020/01/17 06:15:20 (permalink)
0

PIC32MX UART flow control not working in block transfers

Hi all,
 
I'm trying to use a UART to communicate with a 4G module (AT command interface) using a very high baud rate.
Setup:
  MPLAB 3.62
  Harmony 2.06
  PIC32MX575F512H
 
The UART is configured to run a 3mbps with RTS/CTS handshaking and DMA:
 
    ...
    /* Set the handshake mode to either simplex or flow control */
    PLIB_USART_HandshakeModeSelect(USART_ID_2, DRV_USART_HANDSHAKE_FLOWCONTROL);

    /* Initialize the USART based on configuration settings */
    PLIB_USART_InitializeModeGeneral(USART_ID_2,
            false, /*Auto baud*/
            false, /*LoopBack mode*/
            false, /*Auto wakeup on start*/
            false, /*IRDA mode*/
            false); /*Stop In Idle mode*/

    /* Set the line control mode */
    PLIB_USART_LineControlModeSelect(USART_ID_2, DRV_USART_LINE_CONTROL_8NONE1);

    /* We set the receive interrupt mode to receive an interrupt whenever FIFO
       is not empty */
    PLIB_USART_InitializeOperation(USART_ID_2,
            USART_RECEIVE_FIFO_ONE_CHAR,
            USART_TRANSMIT_FIFO_IDLE,
            USART_ENABLE_TX_RX_CTS_RTS_USED);

    /* Get the USART clock source value*/
    clockSource = SYS_CLK_PeripheralFrequencyGet ( CLK_BUS_PERIPHERAL_1 );

    /* Set the baud rate and enable the USART */
    PLIB_USART_BaudSetAndEnable(USART_ID_2,
            clockSource,
            3000000 ); /*Desired Baud rate value*/
 
    /* Clear the interrupt status flags to be on the safer side*/
    SYS_INT_SourceStatusClear(INT_SOURCE_USART_2_TRANSMIT);
    SYS_INT_SourceStatusClear(INT_SOURCE_USART_2_RECEIVE);
    SYS_INT_SourceStatusClear(INT_SOURCE_USART_2_ERROR);
    SYS_INT_SourceStatusClear(INT_SOURCE_DMA_1);
    
    /* Enable the error interrupt source */
    SYS_INT_SourceEnable(INT_SOURCE_USART_2_ERROR);
   ...

 
The transfers appear to work fine, when one byte at a time is sent, regardless of amount of data that is sent. This has a huge overhead associated with it over sending blocks of data at once (it more than halves the effective baud rate). Each character is loaded individually in the UART's tx complete callback and then sends the start/stop bits with each byte. But I don't see any transfer failures.
 
When I send blocks of data at once to get higher throughput, the handshaking really kicks in. However, it seems that every now and again (e.g. every >1MB of data) single bytes are not received by the 4G module. This would suggest that the PIC is sending a byte even though the 4G module is telling it not to. I also don't get an overrun or framing error at the PIC, so I'm unsure how to identify and handle this.
 
Is this a known issue (I can't see anything in the errata)?
Has anyone else had issues with high baud rates and flow control?
Is there anything I need to do to get notified of overrun errors?
If I can get the overrun errors working, how do I resend the failed byte within the Harmony framework?
 
Any help with this would be much appreciated.
Kind Regards
- Oliver
 
 
#1

6 Replies Related Threads

    nigelwright7557
    Super Member
    • Total Posts : 342
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: PIC32MX UART flow control not working in block transfers 2020/01/17 07:03:43 (permalink)
    5 (1)
    If you have a buffer at the receive end stop the flow when the buffer is 90% full.
     
    Perhaps the transmitter has started sending a byte just before flow is stopped ?
     
    #2
    dr_lewis
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2016/01/21 06:57:22
    • Location: 0
    • Status: offline
    Re: PIC32MX UART flow control not working in block transfers 2020/01/17 07:26:20 (permalink)
    0
    Thanks for the quick response Nigel.
     
    "If you have a buffer at the receive end stop the flow when the buffer is 90% full."
    I don't have any control over the buffering in the 4G module. That's an off-the-shelf IC.
     
    "Perhaps the transmitter has started sending a byte just before flow is stopped ?"
    Agree, that is highly likely, though I would expect that to throw an overflow error. In my BufferQueueEventHandler (= IRQ completion callback), I don't see any error events, and I do check for them. 
    #3
    dr_lewis
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2016/01/21 06:57:22
    • Location: 0
    • Status: offline
    Re: PIC32MX UART flow control not working in block transfers 2020/01/17 07:53:57 (permalink)
    0
    Nigel,
    On your second point. That scenario should be fine. The UART should behave as follows (quoted from a datasheet):
     
    "As long as a device is ready to accept more data, it will keep the RTS line asserted. It will deassert RTS some time before its receive buffer is full. There might still be data on the line and in the other device transmit registers which has to be received even after RTS has been deasserted. The other device is required to respect the flow control signal and pause the transmission until RTS is again asserted."
     
    So in fact, there will be no overflow error, but the byte should not be lost either. Nonetheless, it seems to be going missing in my case. Any thoughts on how I can verify whether it is the PIC sending after RTS has been asserted or the receiver throwing away characters away too early?
     
    - Oliver
    #4
    dr_lewis
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2016/01/21 06:57:22
    • Location: 0
    • Status: offline
    Re: PIC32MX UART flow control not working in block transfers 2020/01/17 07:53:57 (permalink)
    0
    Nigel,
    On your second point. That scenario should be fine. The UART should behave as follows (quoted from a datasheet):
     
    "As long as a device is ready to accept more data, it will keep the RTS line asserted. It will deassert RTS some time before its receive buffer is full. There might still be data on the line and in the other device transmit registers which has to be received even after RTS has been deasserted. The other device is required to respect the flow control signal and pause the transmission until RTS is again asserted."
     
    So in fact, there will be no overflow error, but the byte should not be lost either. Nonetheless, it seems to be going missing in my case. Any thoughts on how I can verify whether it is the PIC sending after RTS has been asserted or the receiver throwing away characters away too early?
     
    - Oliver
    #5
    dr_lewis
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2016/01/21 06:57:22
    • Location: 0
    • Status: offline
    Re: PIC32MX UART flow control not working in block transfers 2020/01/17 08:40:40 (permalink)
    5 (1)
    I have managed to dig out some obscure application note on the 4G module that claims it can accept up to 64 byte after its CTS line is de-asserted. That may explain where I'm going wrong, I just preload the DMA with up to 2048 bytes and send it, assuming that the DMA will check the RTS pin with every byte.
     
    I'll try to split the sends into 64 byte chunks, that way the overhead will be much less than sending single bytes and should fit with the 4G module's UART buffering. It's then only critical that the DMA module checks the RTS pin with the first byte.
     
    This will take me a few days to test as my hardware is off site just now. Will let you know if that fixes my issues.
    Thank you Nigel for pointing me in the right direction.
    #6
    ric
    Super Member
    • Total Posts : 25502
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC32MX UART flow control not working in block transfers 2020/01/17 23:57:40 (permalink)
    0
    It sounds like you're approaching a solution, but I would like to query this point

    ...
    The transfers appear to work fine, when one byte at a time is sent, regardless of amount of data that is sent. This has a huge overhead associated with it over sending blocks of data at once (it more than halves the effective baud rate). Each character is loaded individually in the UART's tx complete callback and then sends the start/stop bits with each byte. But I don't see any transfer failures.

    That sounds like a very inefficient way to send it.
    Your device has an 8 byte transmit FIFO which you are defeating.
    You should write bytes until the FIFO is full, then either keep polling it for one FIFO space free, if you can afford to use blocking code, or get it to interrupt as soon as there's any space in the FIFO.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #7
    Jump to:
    © 2020 APG vNext Commercial Version 4.5