USART DMA immediately indicates error but no error flag is set
I'm trying to use DMA with the USART2 receiver in half-duplex mode but the DMA indicates a device error as soon as it begins even though no error flag is set in the ISR register either before the DMA starts or after the DMA ends, additionally the same code works fine when reading the RDR register in a loop. After the DMA fails the data that it should have received can still be read from the USART. I'm also using the same DMA for USART3 in an identical way aside from it not being used in half-duplex mode. So does anyone know what could be causing this?
Here is my code and the output:
TMC_UART_Internal.CR1.TE := False;
for Byte of Input loop
Transmit (TMC_UART, UInt9 (Byte));
Server_Communication.Transmit_String_Line ("In TX FIFO: " & Byte'Image);
end loop;
Server_Communication.Transmit_String ("ISR: ");
Server_Communication.Transmit_String_Line (TMC_UART_Internal.ISR'Image);
Start_Transfer
(This => TMC_UART_DMA_RX_Controller,
Stream => TMC_UART_DMA_RX_Stream,
Source => Read_Data_Register_Address (TMC_UART),
Destination => RX_Buffer'Address,
Data_Count => RX_Buffer'Length);
TMC_UART_Internal.CR1.TE := True;
declare
Error : DMA_Error_Code;
begin
Poll_For_Completion
(This => TMC_UART_DMA_RX_Controller,
Stream => TMC_UART_DMA_RX_Stream,
Expected_Level => Full_Transfer,
Timeout => Milliseconds (100),
Result => Error);
if Error /= DMA_No_Error then
Server_Communication.Transmit_String_Line ("RX data:");
while Rx_Ready (TMC_UART) or TMC_UART_Internal.ISR.BUSY loop
Server_Communication.Transmit_String_Line (TMC_UART_Internal.RDR.RDR'Image);
end loop;
Server_Communication.Transmit_String ("TMC DMA error: ");
Server_Communication.Transmit_String_Line (Error'Image);
Server_Communication.Transmit_String_Line ("DMA received data: ");
Server_Communication.Transmit_String_Line (RX_Buffer'Image);;
Server_Communication.Transmit_String ("ISR: ");
Server_Communication.Transmit_String_Line (TMC_UART_Internal.ISR'Image);
while Rx_Ready (TMC_UART) or TMC_UART_Internal.ISR.BUSY loop
Server_Communication.Transmit_String_Line (TMC_UART_Internal.RDR.RDR'Image);
end loop;
Receive_Failed := True;
else
Server_Communication.Transmit_String ("TMC DMA good: ");
Server_Communication.Transmit_String_Line (Error'Image);
Server_Communication.Transmit_String_Line (Input'Image);
Server_Communication.Transmit_String_Line (RX_Buffer'Image);
end if;
end;
In TX FIFO: 5
In TX FIFO: 1
In TX FIFO: 4
In TX FIFO: 30
ISR:
(PE => FALSE,
FE => FALSE,
NF => FALSE,
ORE => FALSE,
IDLE => FALSE,
RXNE => FALSE,
TC => FALSE,
TXE => TRUE,
LBDF => FALSE,
CTSIF => FALSE,
CTS => FALSE,
RTOF => FALSE,
EOBF => FALSE,
UDR => FALSE,
ABRE => FALSE,
ABRF => FALSE,
BUSY => FALSE,
CMF => FALSE,
SBKF => FALSE,
RWU => FALSE,
WUF => FALSE,
TEACK => FALSE,
REACK => TRUE,
TXFE => FALSE,
RXFF => FALSE,
TCBGT => FALSE,
RXFT => FALSE,
TXFT => TRUE,
RESERVED_28_31 => 0)
RX data: (Note that busy has not even been set at this point, but the DMA has already indicated an error)
TMC DMA error: DMA_DEVICE_ERROR
DMA received data: (Note that 123 was put there by me to make sure that DMA was not writing to the buffer)
[ 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123]
ISR:
(PE => FALSE,
FE => FALSE,
NF => FALSE,
ORE => FALSE,
IDLE => FALSE,
RXNE => FALSE,
TC => FALSE,
TXE => TRUE,
LBDF => FALSE,
CTSIF => FALSE,
CTS => FALSE,
RTOF => FALSE,
EOBF => FALSE,
UDR => FALSE,
ABRE => FALSE,
ABRF => FALSE,
BUSY => TRUE,
CMF => FALSE,
SBKF => FALSE,
RWU => FALSE,
WUF => FALSE,
TEACK => TRUE,
REACK => TRUE,
TXFE => FALSE,
RXFF => FALSE,
TCBGT => FALSE,
RXFT => TRUE,
TXFT => TRUE,
RESERVED_28_31 => 0)
5
1
4
30
30
30
30
30
30
