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

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

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!!!" ?
 

0 Likes
11 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
Anonymous
Not applicable

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.

0 Likes
Anonymous
Not applicable

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.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Do not believe in comments, add a CyGlobalIntEnable

   

 

   

Bob

0 Likes
Anonymous
Not applicable

That did it, Bob. Thanks.  

   

Jean.

0 Likes
Anonymous
Not applicable

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.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
Anonymous
Not applicable

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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

   

 

   

Bob

0 Likes
Anonymous
Not applicable

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?

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Because the buffer size was set to 64 (as needed) the transfer from buffer to FIFO is done in an interrupt handler. This cannot be called when the global interrupts are not enabled.

   

 

   

Bob