You are here

CY8CKIT-058 Bootloader generated UART code stops transmitting once buffer is full | Cypress Semiconductor

CY8CKIT-058 Bootloader generated UART code stops transmitting once buffer is full

Summary: 11 Replies, Latest post by Bob Marlowe on 07 Nov 2016 11:44 AM PST
Verified Answers: 2
Last post
Log in to post new comments.
Jean.Boucher_1839961's picture
User
7 posts

I have a simple Bootloader test program that shows the generated code for the 5LP gets stuck once the 64 char SW FIFO gets full (Write index = 63, Read index = 0).

For some reason, the  UART code seems to stop pulling from the FIFO. It gets stuck in UART1_PutChar() at line 1067 of .\Generated_Source\PSoC5\UART1.c :

        do
        { /* Block if software buffer is full, so we don't overwrite. */

        #if ((UART1_TX_BUFFER_SIZE > UART1_MAX_BYTE_VALUE) && (CY_PSOC3))
            /* Disable TX interrupt to protect variables from modification */
            UART1_DisableTxInt();
        #endif /* (UART1_TX_BUFFER_SIZE > UART1_MAX_BYTE_VALUE) && (CY_PSOC3) */

            locTxBufferWrite = UART1_txBufferWrite;
            locTxBufferRead  = UART1_txBufferRead;

        #if ((UART1_TX_BUFFER_SIZE > UART1_MAX_BYTE_VALUE) && (CY_PSOC3))
            /* Enable interrupt to continue transmission */
            UART1_EnableTxInt();
        #endif /* (UART1_TX_BUFFER_SIZE > UART1_MAX_BYTE_VALUE) && (CY_PSOC3) */
        }
-->     while( (locTxBufferWrite < locTxBufferRead) ? (locTxBufferWrite == (locTxBufferRead - 1u)) :
                                ((locTxBufferWrite - locTxBufferRead) ==
                                (uint8)(UART1_TX_BUFFER_SIZE - 1u)) );

All I see are the first 2 chars ("..") on my terminal before everything stops in this simple test setup to reproduce the problem on my CY8CKIT-058 board:

#include <project.h>

int main()
{
    UART1_CyBtldrCommStart();           // Starts the communication interface and enables its interrupts & callbacks
    
    char str[] = ".";            //"\r\nThis is a sample string.";
    uint16 written = 0;
    cystatus ret = CYRET_SUCCESS;
    for (uint16 loopCount = 0; ret == CYRET_SUCCESS; loopCount++)
    {
        Pin_User_LED_Write(loopCount & 1);
        //UART1_PutChar('.');
        ret = UART1_CyBtldrCommWrite((uint8 *)str, sizeof(str), &written, 0);
        //CyDelay(10 * UART1_BL_CHK_DELAY_MS);                   <----- this keeps it from getting stuck at a full FIFO
    }

}

Environment:
PSoC Creator  4.0 (4.0.0.432)
Culture: English (United States)
OS Version: Microsoft Windows NT 6.1.7601 Service Pack 1
CLR Version: 4.0.30319.42000

Installed CyInstaller Products:
CY8CKIT-059 PSoC 5LP Prototyping Kit 1.0 Rev.**
Cypress Document Manager 1.0 SP1
Peripheral Driver Library 2.1.0
PSoC Programmer 3.25.0
PSoC Creator 3.3 CP3
PSoC Creator 4.0        <--- using this one

Bootloader v1.50

cy_boot v5.50

UART v2.50

UART_Rx/Tx cy_pins v2.20

Anybody should be able to reproduce this with PSoC Creator 4.0, a CY8CKIT-059, a simple project with only a Bootloader component (mine is set for Dual-application mode) and a UART component, and the main() of main.c I pasted above. Can anybody explain why that's happening before I cry "BUG!!!" ?
 

user_1377889's picture
User
9583 posts

Welcome in the forum, Jean.

Can you please post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.

 

Bob

Jean.Boucher_1839961's picture
User
7 posts

Here you go, Bob. See attached archive.  The filename says "...(2 Projects)..." when there's actually 3 (guess that's a "feature"), but you can ignore the PSoC_App[1/2]' projects. All this test needs is the 'PSoC Btldr' project (I build all projects but only program ".\PSoC_Btldr\PSoC_Btldr.cydsn\CortexM3\ARM_GCC_493\Debug\PSoC_Btldr.hex") since I'm only trying to show the bootloader can't reliably communicate through the UART.

Jean.Boucher_1839961's picture
User
7 posts

BTW, my 2 apps (PSoC_App1 and PSoC_App2) this bootloader's previous main() could boot appear to use the same (copy-&-pasted) UART component without any problem.

user_1377889's picture
User
9583 posts

Do not believe in comments, add a CyGlobalIntEnable

 

Bob

Jean.Boucher_1839961's picture
User
7 posts

That did it, Bob. Thanks.  

Jean.

Jean.Boucher_1839961's picture
User
7 posts

I would expect that a call to CyGlobalIntEnable would be done as part of  UART1_CyBtldrCommStart() since the Bootloader component forces you to set the UART TX/RX buffer sizes to at least 64 Bytes which automatically sets "Internal TX/RX interrupt ISR" to "enable".  To me, this sounds like something that should be corrected in the auto-generated code.

user_1377889's picture
User
9583 posts

Opposed to you, I do not want to have global interrupts enabled implicitly at the time I setup / start my components. I would rather like to determine the moment when the first interrupt may fire.

 

Bob

Jean.Boucher_1839961's picture
User
7 posts

Fair enough, then *_CyBtldrCommStart() should enable the interrupt(s) used for the Comm component it is starting, no?

user_1377889's picture
User
9583 posts

Yes, _Start() sets up the required internal interrupts of a component.

 

Bob

Jean.Boucher_1839961's picture
User
7 posts

That's what I saw in UART1_Init() and UART1_Enable(). So, what was causing the problem I just saw that was corrected by enabling global interrupts, and why did it fix it?

Log in to post new comments.