- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!!!" ?
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do not believe in comments, add a CyGlobalIntEnable
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That did it, Bob. Thanks.
Jean.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fair enough, then *_CyBtldrCommStart() should enable the interrupt(s) used for the Comm component it is starting, no?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, _Start() sets up the required internal interrupts of a component.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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