- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am working on CY8C4246AZI-L445 controller and I want use 4 Uarts with receive interrupt.
Whenever I try to add more than 2 uart block in creator it's giving me errors like MAX NUMBER OF MACROCELLS EXCEEDED.I don't understand how to figure out this issue.
I am not using SCB uart ,using another one.
Please help on this asap.
Thanks in advance
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
as you can see in the component datasheet, page 32, these UARTs are implemented in the UDB blocks.
The maximum UART configuration doesn’t fit in to PSoC 4 device because of maximum number or UDB
macrocells exceeded. There are 8 UDBs, so you can't use more than 2 UART blocks.
Is there any reason for why you don't use UART (SCB mode) ?
Best regards,
Liviu
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Liviu,
Thanks for your reply.
Actually, i have used UART in SCB mode but i couldn't generate UART RX
interrupt that is why i am using UDB.
So now i understood that i can't use 4 UART UDB.
Can i use 4 UART in SCB mode with receive interrupt?
If you have any example code,could you please share with me,it would be
helpful for me.
Thanks and regards,
Amit Jori.
On Tue, Mar 26, 2019 at 2:05 PM Liviu Dogaru <community-manager@cypress.com>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Amit Jori,
Yes, you can use 4 UART in SCB mode with receive interrupt.
According to the component datasheet:
The RX buffer size parameter defines the size (in bytes/words) of memory allocated for a receive data buffer. The RX buffer size minimum value is equal to the RX FIFO depth. The RX FIFO is implemented in hardware. Values greater than the RX FIFO depth up to (2^32 – 2) imply usage of the RX FIFO, a circular software buffer controlled by the supplied APIs, and internal ISR. The software buffer size is limited only by the available memory. The interrupt mode is automatically set to internal and the RX FIFO not empty interrupt source is reserved to manage software buffer operation: move data from the RX FIFO into the circular software buffer.
If you still want to handle UART RX interrupt yourself, set Interrupt to External on UART Advanced tab and check RX FIFO not empty.
RX FIFO not empty – At least one data element is available in the RX FIFO to be read.
Best regards,
Liviu
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Oops, I'm a little bit late ;-(
Anyway let me put my work here 😉
With attached project, I could generate an application and the project could be built.
schematic
main.c
==================
#include "project.h"
volatile int uart1_flag = 0 ;
volatile int uart2_flag = 0 ;
volatile int uart3_flag = 0 ;
volatile int uart4_flag = 0 ;
CY_ISR(uart1_isr)
{
isr_1_ClearPending() ;
uart1_flag = 1 ;
}
CY_ISR(uart2_isr)
{
isr_2_ClearPending() ;
uart2_flag = 1 ;
}
CY_ISR(uart3_isr)
{
isr_3_ClearPending() ;
uart3_flag = 1 ;
}
CY_ISR(uart4_isr)
{
isr_4_ClearPending() ;
uart4_flag = 1 ;
}
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
isr_1_ClearPending() ;
isr_1_StartEx(uart1_isr) ;
isr_2_ClearPending() ;
isr_2_StartEx(uart2_isr) ;
isr_3_ClearPending() ;
isr_3_StartEx(uart3_isr) ;
isr_4_ClearPending() ;
isr_4_StartEx(uart4_isr) ;
UART_1_Start() ;
UART_2_Start() ;
UART_3_Start() ;
UART_4_Start() ;
}
int main(void)
{
init_hardware() ;
for(;;)
{
if (uart1_flag) {
// do something for uart1
uart1_flag = 0 ;
}
if (uart2_flag) {
// do something for uart2
uart2_flag = 0 ;
}
if (uart3_flag) {
// do something for uart3
uart3_flag = 0 ;
}
if (uart4_flag) {
// do something for uart4
uart4_flag = 0 ;
}
}
}
==================
moto
P.S. In my first post, uart4_isr was clearing isr_3 flags (fixed)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you guys for your response.
I'll try these solutions and let you know the results.
regards,
Amit.
On Wed, Mar 27, 2019 at 5:16 AM Motoo Tanaka <community-manager@cypress.com>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Thank you for your help.
With the help of your suggestions, now I am able to generate UART receive
interrupt using SCB UART.
But, for every received byte, its generating interrupt even I disable that
interrupt.
I want to read the complete string on first received byte interrupt for
that I am doing following steps:
1)Send a string of 5 bytes from Tera Term.
2)Once interrupt is generated for the first byte of string, in isr I
Disable the interrupt then
3)Read remaining 5 bytes.
4)After reading, Enable the Interrupt again to receive the next string.
But the problem is, the controller is generating an interrupt for every
received byte and when I try to read the string, it's giving me the same
character 5 times.
For example. If i send data like "ABCD"
for every character, Interrupt is getting generated, you can see from the
attached image file.
After disabling interrupt it should not generate interrupt till I enable
it, but i don't know what i am missing.
Find attached workspace folder and Please help me on this.
Regards,
Amit.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
So I modified main.c as follow.
As you are going to have 4 UARTs, I rename each UART depending variables with the number.
main.c
========================
#include "project.h"
#include "stdio.h"
CY_ISR_PROTO(MyRx1Int); // process Rx interrupt
#define TAB '\t'
#define SPACE ' '
#define CR '\r'
#define LF '\n'
#ifndef STR_1_LENGTH
#define STR_1_LENGTH 32 /* length for UART command input */
#endif
#ifndef BUF_1_LENGTH
#define BUF_1_LENGTH 128
#endif
volatile char rx_1_buf[BUF_1_LENGTH] ; /* buffer for UART_RX */
volatile int rx_1_write_index = 0 ;
int rx_1_read_index = 0 ;
char str_1_buf[STR_1_LENGTH+1] ; /* print buffer */
int str_1_index = 0 ;
inline int is_delimiter(uint8_t c)
{
int result = 0 ;
switch(c) {
// case TAB: // uncoment this line if you need TAB to be a delimiter
// case SPACE: // uncoment this line if you need SPACE to be a delimiter
case CR:
case LF:
result = 1 ;
break ;
}
return( result ) ;
}
CY_ISR(MyRx1Int)
{
uint8_t int_flag ;
UART_1_ClearRxInterruptSource(UART_1_INTR_RX_NOT_EMPTY) ; /* for PSoC 4 */
if (UART_1_SpiUartGetRxBufferSize()) {
int_flag = CyEnterCriticalSection() ;
rx_1_buf[rx_1_write_index] = UART_1_UartGetByte() ;
rx_1_write_index = (rx_1_write_index + 1) % BUF_1_LENGTH ;
CyExitCriticalSection(int_flag) ;
}
}
/*=========================
Main Function
===========================*/
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
UART_1_SpiUartClearRxBuffer() ;
isr_1_StartEx(MyRx1Int);
UART_1_Start();
UART_1_UartPutString("\r\nUART example\r\n");
for(;;)
{
while(rx_1_read_index != rx_1_write_index) {
if (is_delimiter(rx_1_buf[rx_1_read_index])) {
str_1_buf[str_1_index] = 0 ;
UART_1_UartPutString(str_1_buf) ;
UART_1_UartPutString("\n") ;
str_1_index = 0 ;
} else {
str_1_buf[str_1_index++] = rx_1_buf[rx_1_read_index] ;
if (str_1_index >= STR_1_LENGTH) {
str_1_buf[STR_1_LENGTH] = 0 ;
UART_1_UartPutString(str_1_buf) ;
str_1_index = 0 ;
}
}
rx_1_read_index = (rx_1_read_index + 1) % BUF_1_LENGTH ;
}
}
}
========================
Using CY8CKIT-044 the TeraTerm output looked like
moto
P.S. To extract data from the ring buffer, I had to debug a lot and ended up posting this 3rd version 190401B orz
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Motoo,
Thanks for your solution!!
And sorry for late update.
#ifndef STR_1_LENGTH
#define STR_1_LENGTH 32 /* length for UART command input */
#endif
#ifndef BUF_1_LENGTH
#define BUF_1_LENGTH 128
#endif
Can I change these buffers size( 32 ,128 )as per my application?
CyEnterCriticalSection() ;
CyExitCriticalSection(int_flag) ;
Can I use these functions to enable and disable particular interrupt?or
Are they used only for enable/disable all interrupts?
Here i will explain you what i want to implement.
I want to use GSM, GPS, RS232, and RS485 for that i require 4 uarts and I
want to use UART Rx interrupt for both RS232 and RS485 to receive data.
And data string which i am going to receive on RS232 and Rs485 is longer
than 100byte or 200 bytes.
For every 1 or 2 sec, i will have a data string from RS485 and i want send
that received data to server using GSM.
In-between transmitting data to gsm and receiving data from GPS if
interrupt comes,is it going to make any problem?
Because for every received byte, interrupt is generating.
As you know,when we send AT command to GSM module, it sends response,so in
between reading response if i get RS485 RX interrupt there is chance that I
might get miss any response byte from GSM.
Can you suggest me how can I take care of interrupt in this situation.
Please help me on this.
Thanks and regards,
Amit.
On Sun, Mar 31, 2019, 7:50 AM Motoo Tanaka <community-manager@cypress.com>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Amit-san,
> Can I change these buffers size( 32 ,128 )as per my application?
I think so. (you can change them as you like)
But I recommend you to have BUF_LENGTH > STR_LENGTH
so that the UART module will not miss the byte while software can not serve it.
> CyEnterCriticalSection() ;
> CyExitCriticalSection(int_flag) ;
>
> Can I use these functions to enable and disable particular interrupt?or
> Are they used only for enable/disable all interrupts?
This was added to protect the rx_buf[] while unloading the data from UART's rx_buffer.
So if each UART has own rx_buffer (like rx_1_buf, rx_2_buf ..) and
if you are not writing data to that rx_buffer outside of MyRxNInt
this protection may not be necessary, especially, when you need other interrupts to be active.
> And data string which i am going to receive on RS232 and Rs485 is longer
> than 100byte or 200 bytes.
I would recommend you to set the rx_buffer size of UART of RS232 and RS485
longer than the data string, so that missing data will not happen.
When long buffer size is assigned in the Configure of UART,
software ring buffer scheme is used as below.
From the UART Datasheet
===============
The RX buffer size parameter defines the size (in bytes/words) of memory allocated for a receive data buffer. The RX buffer size minimum value is equal to the RX FIFO depth. The RX FIFO is implemented in hardware. Values greater than the RX FIFO depth up to (232 – 2) imply usage of the RX FIFO, a circular software buffer controlled by the supplied APIs, and internal ISR.
===============
> As you know,when we send AT command to GSM module, it sends response,so in
> between reading response if i get RS485 RX interrupt there is chance that I
> might get miss any response byte from GSM.
If you set rx_buffer size for the UART module long enough and the command from RS232 or RX485 won't come without interval missing response should not happen.
Testing should be required to confirm it though.
So I think that assigning enough long rx_buffer(s) for each UARTs will be necessary for your application.
Best Regards,
4-Apr-2019
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Motoo for your quick response.
I will make changes and let you know the result.
Regards,
Amit
On Thu, Apr 4, 2019, 12:55 PM Motoo Tanaka <community-manager@cypress.com>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
amitjori7,
attached is example of fixed function SCB UART Rx for PSoC4200M (KIT-044M). In this demo, simple text commands (e.g. "R255", "G127", "B10") from UART terminal (like TeraTerm or Putty) are used to control RGB LED intensity. Do not forget to use CR, LF (or both) when sending control commands.
I believe that KIT-044 should fit up to 8 SCB UARTs.
/odissey1