Skip to main content
arsi
Associate
October 31, 2011
Question

STM32F103ZE RS485 DMA communication problem

  • October 31, 2011
  • 3 replies
  • 888 views
Posted on October 31, 2011 at 18:54

HI!

I have a problem

with the following code

..

After

a few hours to

several days

.

The maximum

was

to

14 days

Data

transmission

stops working

.

Receive and transmit

works

in

one task

. (BACNET protocol)

For

DMA

uses internal

RAM

.

Receive

a

nd

other

tasks

work

s

further

.

void USART3_SendData(unsigned char buffer[], int Len) {

    if (Len > 500) {

        Len = 500;

    }

    memcpy(TxBuffer3Out, buffer, Len);

    DMA_InitTypeDef DMA_InitStructure5;

    DMA_DeInit(DMA1_Channel2);

    DMA_InitStructure5.DMA_PeripheralBaseAddr = USART3_DR_Base;

    DMA_InitStructure5.DMA_MemoryBaseAddr = TxBuffer3Out;

    DMA_InitStructure5.DMA_DIR = DMA_DIR_PeripheralDST;

    DMA_InitStructure5.DMA_BufferSize = Len;

    DMA_InitStructure5.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

    DMA_InitStructure5.DMA_MemoryInc = DMA_MemoryInc_Enable;

    DMA_InitStructure5.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

    DMA_InitStructure5.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

    DMA_InitStructure5.DMA_Mode = DMA_Mode_Normal;

    DMA_InitStructure5.DMA_Priority = DMA_Priority_Low;

    DMA_InitStructure5.DMA_M2M = DMA_M2M_Disable;

    DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);

    DMA_ITConfig(DMA1_Channel2, DMA_IT_TE, ENABLE);

    DMA_Init(DMA1_Channel2, &DMA_InitStructure5);

    USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);

    DMA_ClearFlag(DMA1_FLAG_TC2);

    NVIC_EnableIRQ(DMA1_Channel2_IRQn);

    RS485_rts_enable(true);

    DMA1_Channel2->CCR |= DMA_CCR2_EN;

    OS_FlagID flag;

    start:

    flag = CoWaitForSingleFlag(USART3txFlag, 500);

    if (flag != E_OK && flag != E_TIMEOUT) {

         goto start;

    }

    CoTimeDelay(0, 0, 0, 20);

    RS485_rts_enable(false);

}

void DMA1_Channel2_IRQHandler(void) {//USART3 TX

    if (DMA_GetITStatus(DMA1_IT_HT2) == SET) {

        DMA_ClearITPendingBit(DMA1_IT_HT2);

    } else if (DMA_GetITStatus(DMA1_IT_TC2) == SET) {

        DMA_ClearITPendingBit(DMA1_IT_TC2);

        USART_ITConfig(USART3, USART_IT_TC, ENABLE);

    } else if (DMA_GetITStatus(DMA1_IT_TE2) == SET) {

        DMA_ClearITPendingBit(DMA1_IT_TE2);

    }

    return;

}

void USART3_IRQHandler(void) {

    if (USART_GetITStatus(USART3, USART_IT_TC) == SET) {

        USART_ClearITPendingBit(USART3, USART_IT_TC);

        USART_ITConfig(USART3, USART_IT_TC, DISABLE);

        CoEnterISR();

        isr_SetFlag(USART3txFlag);

        CoExitISR();

        return;

    }

}

Any

idea

??

Thanks!!

ArSi
    This topic has been closed for replies.

    3 replies

    Tesla DeLorean
    Guru
    November 1, 2011
    Posted on November 01, 2011 at 01:37

    I'm unsure of the wisdom of constantly enabling/disabling interrupts, especially the USART TC one. And the point of having DMA interrupts if you're not actually doing anything with them.

    I guess I'd attack this keeping the USART TC interrupt enabled, because it will always trail the DMA completion, and use it to progress the USART DMA to the next.

    Consider a method of chaining the pending data so it can transition more seamlessly between blocks of DMA'd data.

    Is all data on the USART sent via DMA?

    In terms of debugging the current code, and the failures, you'll need to examine what's not getting signalled, and looking at the USART and DMA registers in the failing condition to see if they are indicative of anything. For example the USART is holding an error state precluding further rx/tx operation until cleared.

    DMA can be very fussy about sequencing.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    arsi
    arsiAuthor
    Associate
    November 1, 2011
    Posted on November 01, 2011 at 10:46

    The

    same code

    I have

    used for

    usart1

    ,

    usart2

    .

    This

    is

    just

    a

    RS232

    ,

    problem does not occur

    .

    Quantity

    of data

    is

    transmitted

    mainly through

    usart1

    significantly larger

    .

    When it comes to

    DMA

    error

    flag

    was

    there

    so I

    included

    the command

    to

    restart

    the processor

    , but

    did not come

    .

    Data

    sent

    completely

    and

    without problems.

    Debugger

    I

    was

    hanging

    there

    already

    3 days

    ,

    but as

    it happens

    error

    had not occurred

    .

    Most

    annoying

    ,

    there are

    lots

    of

    complex

    code.

    And it

    works.

    And

    does not

    thing

    which should

    run without

    problems

    Tesla DeLorean
    Guru
    November 1, 2011
    Posted on November 01, 2011 at 15:03

    there are

    lots

    of

    complex

    code.

    Indeed, perhaps overly so, I'd be worried about your race condition and priority inversion problems, based on the code fragment presented.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..