11 Replies Latest reply on Apr 4, 2019 2:30 AM by amjoc_4089431

    How to use 4 Uart in Psoc 4

    amjoc_4089431

      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 advanceIMG_20190326_121038594.jpg

        • 1. Re: How to use 4 Uart in Psoc 4
          LiDo_2439176

          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

          1 of 1 people found this helpful
          • 2. Re: How to use 4 Uart in Psoc 4
            amjoc_4089431

            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>

            • 3. Re: How to use 4 Uart in Psoc 4
              BoTa_264741

              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

              UART_SCB_Rx_01.png


               

              • 4. Re: How to use 4 Uart in Psoc 4
                LiDo_2439176

                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

                • 5. Re: How to use 4 Uart in Psoc 4
                  MoTa_728816

                  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

                  000-schematic.JPG

                   

                  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)

                  • 6. Re: How to use 4 Uart in Psoc 4
                    amjoc_4089431

                    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>

                    • 7. Re: How to use 4 Uart in Psoc 4
                      amjoc_4089431

                      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.

                      • 8. Re: How to use 4 Uart in Psoc 4
                        MoTa_728816

                        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

                        001-TeraTerm-log.JPG

                        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

                        • 9. Re: How to use 4 Uart in Psoc 4
                          amjoc_4089431

                          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>

                          • 10. Re: How to use 4 Uart in Psoc 4
                            MoTa_728816

                            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

                            • 11. Re: How to use 4 Uart in Psoc 4
                              amjoc_4089431

                              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>