1 2 Previous Next 15 Replies Latest reply on Aug 30, 2017 9:33 PM by moro_1580446

    UART-DMA and Break

      Hello Forum,

         

      i have made an 4 Channel-DMX Receiver with the PSoc5 Kit and it works fine with Interrupt based Code:

         

      CY_ISR(ISR_DMX1)
      {
          // Check for break
          if((UART_1_ReadRxStatus() & UART_1_RX_STS_BREAK) != 0)
          {
              DMX1Pointer = 0;
          }
          else //Read the Byte and store it in the Array
          {
              DMXIn1[DMX1Pointer] = UART_1_ReadRxData();
              DMX1Pointer++;
          }
      }

         

      Now i want to do this with DMA. I think there is no Problem to store the Bytes, but how do i reset the Stream when a Break of the UART is detected?

         

      Günter

        • 1. Re: UART-DMA and Break
          JoMe_264151

          You do not have any way to decide on DMA data transferred. You'll have to keep on using interrupts. Because of the comparable low speed of a UART there is no need using DMA, CPU stress is low.

             

           

             

          Bob

          • 2. Re: UART-DMA and Break

            Hmm,

               

            one DMX-Frame generates 514 Interrupts and is about 22,667ms long. So there are 1/0,022667 = 44,12 Frames per Second

               

            44,12 * 514 = 22677 Interrupts per Second.

               

            4 DMX Inputs and 1 Output = 113385 Interrupts per Second.

               

            At least i try to make the DMX output with DMA.

               

            Send the 513 Bytes, generate an Interrupt when all Bytes are copied and generate the Break in the Interrupt.

               

            Then start DMA again.

               

            Attached the Project. The Break is made with Delays in the Interrupt right now. The next Step is to replace this with a interruptbased PWM to avoid the Delays.

               

            Günter

            • 3. Re: UART-DMA and Break
              BoTa_264741
                      In the code above you use 1 interrupt per Rx character. Instead, you can use a circular buffer to copy all characters available in Rx buffer, until the whole frame is received. This way the amount of interrupts fired will drop substantially. I see no problems reading 4x UART channels using PSoC. P.S. some old circular buffer example is attached P.P.S. never use Delay functions inside ISR.   
              • 4. Re: UART-DMA and Break

                Hello Odissey,

                   

                the Delays in the Interrupt is fixed. I use a PWM Component to generate the Break and disconnect the TX with an AND during the BREAK.

                   

                I think the circular Buffer will also use Interrupts internally. So the amount will be the same, or is there a Hardwarebuffer?

                   

                Günter

                   

                • 5. Re: UART-DMA and Break
                  BoTa_264741
                          From my experience, there are at least several bytes accumulated in the buffer by the time last isr is processed, cleared and next one is fired. So there is a reason to read all content of a buffer until it's empty on each ISR.   
                  • 6. Re: UART-DMA and Break

                    Hello,

                       

                    here are two Versions of the Code . The first one with Interrupts and the BREAK with an PWM-Component. This Code works, but i think it can optimized.

                       

                    The second Code is my try to enable DMA for the TX Way, but it didnt work. I want to transmit 512 Bytes, one Byte after each OnTX-Complete. When all 512 Bytes are sent, an NRQ Interrupt of the DMA generates a BREAK. After this BREAK, DMA is started again. But now the DMA Dont start to transmit Data...

                       

                    Günter

                    • 8. Re: UART-DMA and Break
                      JoMe_264151

                      Three what?

                         

                       

                         

                      Bob

                      • 9. Re: UART-DMA and Break
                        JoMe_264151

                        #define DMADMX_SRC_BASE (CYDEV_SRAM_BASE)
                        #define DMADMX_DST_BASE (CYDEV_SRAM_BASE)

                           


                        Source is not sram, but peripheral!

                           

                            CyDmaTdSetConfiguration(DMADMX_TD[0], 512, DMADMX_TD[0], CY_DMA_TD_INC_SRC_ADR);

                           


                        You should increment the destination, not the source.

                           

                            CyDmaTdSetAddress(DMADMX_TD[0], LO16((uint32)&DMXOut[1]), LO16((uint32)UARTOUT_TXDATA_PTR));

                           


                        You swapped source and destination.

                           

                         

                           

                        I cannot see the place where you restart the DMA when finished.

                           

                         

                           

                        Bob

                        • 10. Re: UART-DMA and Break

                          Hello Bob,

                             

                          42!

                             

                          The DMA is for TX. I want to send Data from Array to Uart.

                             

                          #define DMADMX_SRC_BASE (CYDEV_SRAM_BASE)
                          #define DMADMX_DST_BASE (CYDEV_PERIPH_BASE)

                             

                          How do i restart the DMA?

                             

                          CyDmaChEnable(DMADMX_Chan, 1); //?

                             

                           

                             

                          Günter

                          • 11. Re: UART-DMA and Break

                            Hello,

                               

                            now TX with DMA is working. I have to send 515 Bytes because the NRQ of the DMA is fired before all 513 Bytes were sent.

                               

                            Thanks for the help.

                               

                            Now i try to optimize RX...

                               

                            Günter

                            • 12. Re: UART-DMA and Break

                              Hello,

                                 

                              is it possible to get seperate Interrupts from an UART Component? One for OnByteReceived and one for OnBreak?

                                 

                              Günter

                              • 13. Re: UART-DMA and Break
                                JoMe_264151

                                CyDmaChEnable(DMADMX_Chan, 1); //?  Yes

                                   

                                 

                                   

                                Bob

                                • 14. Re: UART-DMA and Break

                                  Hello,

                                     

                                  now the Inputs also work with DMA. I used a Timer to detect the Break and fire an Interrupt, because i found no way to generate an seperate Interrupt onBreak in the UART Component.

                                     

                                  Each Input has one Interrupt per Break (per Frame). The Output has two Interrups per Frame. One at the beginning of the Brake, on at the End of the Brake.

                                     

                                  Günter

                                  1 2 Previous Next