Thread: Why SERCOM1_USART_Write function cannot be used twice in a row?

  1. #1
    Registered User
    Join Date
    Mar 2021
    Posts
    17

    Why SERCOM1_USART_Write function cannot be used twice in a row?

    For a PIC32CM processor, I am trying to use the UART write function twice in a row. The project is built from Harmony3.

    SERCOM1_USART_Write(char_array1, sizeof(char_array1));
    SERCOM1_USART_Write(char_array2, sizeof(char_array2));

    When the code is executed, only string1 is displayed.

    I introduced various delay methods in between the two writes without success.

    Does anyone have a solution or workaround?

    Thanks.
    Last edited by boomeral; 06-15-2021 at 06:28 AM. Reason: added information.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    How about posting more than 2 lines of code.

    How is it called?
    How are those variables declared and initialised?

    Using sizeof() on a char array means you're going to send a \0, and that may be bad news to whatever is listening at the other end.

    Maybe try it with strlen() instead.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2021
    Posts
    25
    Using sizeof() on a char array means you're going to send a \0
    Depending on how the "array" is declared, it can also mean that what you pass to sizeof might be a pointer so it returns that size, not the array's! We really need to see more code to be sure what's going on.

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    1,628
    Maybe you need to do something like this:
    Code:
    void print_string(const char *str)
    {
        for (const char *s = str, *end = str + strlen(str); s != end; )
        {
            if (SERCOM1_USART_WriteFreeBufferCountGet() > 0)
                s += SERCOM1_USART_Write((uint8_t*)s, end - s);
            else
                // If you have a better way to wait, use it
                for (size_t i = 0; i < 1000000; ++i) ;  // busy wait
        }
    }
     
    void some_func()
    {
        print_string("hello");
        print_string("world");
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    505
    Quote Originally Posted by boomeral View Post
    For a PIC32CM processor, I am trying to use the UART write function twice in a row. The project is built from Harmony3.

    SERCOM1_USART_Write(char_array1, sizeof(char_array1));
    SERCOM1_USART_Write(char_array2, sizeof(char_array2));

    When the code is executed, only string1 is displayed.

    I introduced various delay methods in between the two writes without success.

    Does anyone have a solution or workaround?

    Thanks.

    Unless someone here has the exact same system, they can only speculate. One possibility which has been mentioned is that char_array2 is a pointer, in which case sizeof() will yield a value of probably 4. But then you would see the first four characters.

    The thing to do when faced with these sorts of situations is to fiddle with it. The first call works. That's very good, it means you have some output to work with.
    So try reversing the order so char_array2 is called first. What happens? Replace the arrays with literals? Does it work as expected? Call char_array1 twice. Is the second call still suppressed?

    You gradually home in on what is causing the problem.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  6. #6
    Registered User
    Join Date
    Mar 2021
    Posts
    17
    Thanks to EVERYONE replied to my question. I appreciate your suggestions. You are awesome!

    I admit that I assumed things in my original post hence the replies can only be speculative.
    Included in this reply is an example project for the Microchip Curiosity Pro development board. I know you will not have the same setup, but you will have the knowledge of how the project is setup.
    This project echoes 10 characters which it receives from a terminal window. Again you will not be able to run without development board. At the start of execution, it displays a message on the terminal. I added another test message to see if the two messages can be displayed one after another - it fails.
    In main.c lines 107 and 109 are the two attempts to write to SERCOM. Only the first write is successful. I have tried adding delays in between the two writes, rearranging the two, writing the same string twice - only one write is displayed on the terminal for every mod.

    usart_echo_interrupt.zip - Google Drive

    Thanks,

    --boomer

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    So why do you think SERCOM0_USART_Write and SERCOM1_USART_Write are the same thing?

    Why do you refuse to post your code; note posting some one else's code does not count!

    Code:
    /*******************************************************************************
      SERCOM Universal Synchronous/Asynchrnous Receiver/Transmitter PLIB
    
      Company
        Microchip Technology Inc.
    
      File Name
        plib_sercom0_usart.h
    
      Summary
        USART peripheral library interface.
    
      Description
        This file defines the interface to the USART peripheral library. This
        library provides access to and control of the associated peripheral
        instance.
    
      Remarks:
        None.
    *******************************************************************************/
    
    /*******************************************************************************
    * Copyright (C) 2018 Microchip Technology Inc. and its subsidiaries.
    *
    * Subject to your compliance with these terms, you may use Microchip software
    * and any derivatives exclusively with Microchip products. It is your
    * responsibility to comply with third party license terms applicable to your
    * use of third party software (including open source software) that may
    * accompany Microchip software.
    *
    * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
    * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
    * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
    * PARTICULAR PURPOSE.
    *
    * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
    * INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
    * WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
    * BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
    * FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
    * ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
    * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
    *******************************************************************************/
    
    #ifndef PLIB_SERCOM0_USART_H // Guards against multiple inclusion
    #define PLIB_SERCOM0_USART_H
    
    // *****************************************************************************
    // *****************************************************************************
    // Section: Included Files
    // *****************************************************************************
    // *****************************************************************************
    
    #include "plib_sercom_usart_common.h"
    
    // DOM-IGNORE-BEGIN
    #ifdef __cplusplus // Provide C++ Compatibility
    
        extern "C" {
    
    #endif
    // DOM-IGNORE-END
    
    // *****************************************************************************
    // *****************************************************************************
    // Section: Interface Routines
    // *****************************************************************************
    // *****************************************************************************
    
    void SERCOM0_USART_Initialize( void );
    
    bool SERCOM0_USART_SerialSetup( USART_SERIAL_SETUP * serialSetup, uint32_t clkFrequency );
    
    void SERCOM0_USART_TransmitterEnable( void );
    
    void SERCOM0_USART_TransmitterDisable( void );
    
    bool SERCOM0_USART_Write( void *buffer, const size_t size );
    
    
    bool SERCOM0_USART_WriteIsBusy( void );
    
    size_t SERCOM0_USART_WriteCountGet( void );
    
    void SERCOM0_USART_WriteCallbackRegister( SERCOM_USART_CALLBACK callback, uintptr_t context );
    
    
    void SERCOM0_USART_ReceiverEnable( void );
    
    void SERCOM0_USART_ReceiverDisable( void );
    
    bool SERCOM0_USART_Read( void *buffer, const size_t size );
    
    bool SERCOM0_USART_ReadIsBusy( void );
    
    size_t SERCOM0_USART_ReadCountGet( void );
    
    bool SERCOM0_USART_ReadAbort(void);
    
    void SERCOM0_USART_ReadCallbackRegister( SERCOM_USART_CALLBACK callback, uintptr_t context );
    
    USART_ERROR SERCOM0_USART_ErrorGet( void );
    
    uint32_t SERCOM0_USART_FrequencyGet( void );
    
    // DOM-IGNORE-BEGIN
    #ifdef __cplusplus  // Provide C++ Compatibility
    
        }
    
    #endif
    // DOM-IGNORE-END
    
    #endif //PLIB_SERCOM0_USART_H
    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    So what does this do?
    Code:
        SERCOM0_USART_Write("", 1);
        SERCOM0_USART_Write(&message[0], sizeof(message));
    If you don't see message, then try replacing all the sizeof with strlen.
    sizeof() will send a \0, whereas strlen() won't.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Mar 2021
    Posts
    17
    Mr. stahta01 - excuse me if I am misspelling your name here.

    What difference does it make if a cat chases mouse #1 or mouse #2 especially when they twins?????

  10. #10
    Registered User
    Join Date
    Mar 2021
    Posts
    17
    Hi Salem,

    The results are still the same - single output - for both of your suggestions.

    Thanks for the help

    --boomer

  11. #11
    Registered User
    Join Date
    Mar 2021
    Posts
    17
    It turned out Harmony3 has a function for such a scenario called SERCOM0_USART_WriteIsBusy(). My suspicion is that write buffer is not empty until much later and another write after the first one is simply ignored especially since the write function is nonblocking. So modifying the code slightly as follows produced the expected result - successful writes one after another.

    SERCOM0_USART_Write(&messageStart[0], sizeof(messageStart));

    while( SERCOM0_USART_WriteIsBusy() );

    SERCOM0_USART_Write(&messageStart[0], sizeof(messageStart));


    Thanks to all who took the time to suggest the solution and for those whiny tincans - learn to help people and just don't nitpick.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-19-2020, 05:50 AM
  2. Function Prototype, Function Call, and Function definition
    By dmcarpenter in forum C Programming
    Replies: 9
    Last Post: 04-09-2013, 03:29 AM
  3. Replies: 13
    Last Post: 03-20-2012, 08:29 AM
  4. Print function: sending a function.. through a function?
    By scarlet00014 in forum C Programming
    Replies: 3
    Last Post: 11-05-2008, 05:03 PM
  5. Replies: 9
    Last Post: 01-02-2007, 04:22 PM

Tags for this Thread