UART-DMA and Break

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

cross mob
Anonymous
Not applicable

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

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

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

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

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

0 Likes
lock attach
Attachments are accessible only for community members.
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted
        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.   
0 Likes
Anonymous
Not applicable

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

   

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted
        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.   
0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

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

0 Likes
Anonymous
Not applicable

3

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

Three what?

   

 

   

Bob

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

#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

0 Likes
Anonymous
Not applicable

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

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

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

0 Likes
Anonymous
Not applicable

Hello,

   

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

   

Günter

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

CyDmaChEnable(DMADMX_Chan, 1); //?  Yes

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

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

0 Likes

Hi every body.I have a question.why you use break generator in your project?can we use uart and dma alone to transfer data ?

because now i have a problem in my project . cpu has to work for several duty as CAN interface and adc and i2c and gsm and gps module.then transfer data on rs232 and gsm module.so if i dont use dma in my project,cpu is worked bad and data is being mixed up.

I think my big problem is transfer big data on rs232 quickly . how can i do cpu free from rs232?

please help me to solve this problem???

thanks for attention...

0 Likes