0
\$\begingroup\$

I`m using STM32F103CBT6 core with UART via DMA on 9600 baud rate.

The device in idle state transfers data between controller and bill validator unit. In the same time I`m sniffing the data that are going there.

When I need to emulate the bill validator and send my own commands to the controller I just switching logical ICs (to break up the communication between them) and sending my own data to the USART 2.

My application works generally fine except one issue. I found out that sometimes the data seems to be corrupted. To show the issue I prepares some screenshots from the logic analyzer app:

Here is the correct data packet: The data packet that contains correct data

And here is the corrupted data packet: Corrupted one

Of course I tried to debug it with ST-Link but I saw that data array that is going to the HAL_UART_Transmit_DMA function is correct. I also tried to make an array to be const (as the original data packet`s CRC - last two bytes - are dynamically calculated) but without success.

So here I`m sure that data that going to the HAL library is correct.

I don`t know where to search now but I guess that the problem is with DMA.

I didn`t received any data while transmitting on that UART, and sending new data packet way after the previous one was sent.

P.S. I need to add that the problem is not constant but happens on 1 of the ~10-20 transfers. At the same time the corrupted packet looks every time the same. I guess it related to that fact that request command also the same every time.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I need someone to approve but seems that I found out my problem.

Here is my code snippet where I`m sending the data:

case IDENTIFICATION_CMD:
uint8_t identification_response[IDENTIFICATION_LNG] = {0x00};

identification_response[0] = SYNC;
identification_response[1] = ADR;
identification_response[2] = IDENTIFICATION_LNG;

memcpy(identification_response + 3, emu.part_number, sizeof(emu.part_number));
memcpy(identification_response + 3 + sizeof(emu.part_number), emu.serial_number, sizeof(emu.serial_number));
memcpy(identification_response + 3 + sizeof(emu.part_number) + sizeof(emu.serial_number), emu.asset_number, sizeof(emu.asset_number));

calculate_CRC(identification_response, IDENTIFICATION_LNG - CRC_LNG, identification_response +
        sizeof(emu.part_number) + sizeof(emu.serial_number) + sizeof(emu.asset_number) + (IDENTIFICATION_LNG - CRC_LNG));

HAL_UART_Transmit_DMA(CONTROLLER_UART,  identification_response, IDENTIFICATION_LNG);
break;

I created a local array in the function and sending data with UART via DMA from it.

Transmit function call looks like that:

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)

and in the call function I found the following lines:

tmp = (const uint32_t *)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);

And now I understand why that happens. My function ends right after the UART Transmit func call and the local array is also destroyed. But the transmit function gets pointer to the data buffer and you know.

I guess the bug was not constant because of speed of the execution of the main app. Like some interrupt was triggered in the same time which gave some time for DMA to send the whole data packet correctly.

\$\endgroup\$
1
  • \$\begingroup\$ It seems that you partly understood the issue. Your question is not clear as I thought it was about incoming data, but it's about outgoing data. The DMA is operating independently from your program - your code starts the DMA but it's really slow @ 9600 baud to transmit everything. So the buffer needs to exist until everything is transferred. You'ld better allocate a permanent output buffer. Several implementations use 2 buffers: one that is being sent, the other that is filled with the next data to send. When the DMA finishes, an interrupt tells the DMA to send the other buffer... . \$\endgroup\$
    – le_top
    Commented Apr 16 at 15:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.