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

cross mob
Kevingiordano14
Level 2
Level 2
50 sign-ins 10 questions asked 10 replies posted

Hello, everyone.

I'm working on a Tricore TC399 and i would like to try to measure the transfer time from the receiving hw FIFO of the uart to the DSPR0 memory via DMA. For this purpose, I started from the example "UART_DMA_Transfer_1 for KIT_AURIX_TC375_LK".
I first tried to run the code by debugging it, and according to the file "Infineon UART_DMA_Transfer_1_KIT_TC375_LK-Training-v01_00-EN" I should get the value of the variable g_correctTransactions=12 but unexpectedly it turns out to be equal to 1. I don't know if anyone knows what this problem is due to.

Furthermore, my objective is to measure the transfer time of the DMA; I therefore thought of using the Stm module, via two uint64 variables: start and stop. The start variable takes the number of ticks of the stm counter via the function: "(uint64)IfxStm_get(IFXSTM_DEFAULT_TIMER) & TIME_INFINITE;" and this is done inside the function void send_data(void) before the command IfxAsclin_Asc_write(&g_ascHandle, g_txData, &g_count, TIME_INFINITE); .
The stop variable takes the number of ticks always via the function: '(uint64)IfxStm_get(IFXSTM_DEFAULT_TIMER) & TIME_INFINITE;' and this is done inside the ISR of the DMA: void prio_DMA(void).
I wanted to know if this technique is correct and accurate, also because, every time I debug,  I get different results  from the 'start-stop'(which should be the number of ticks between the start of the transmission and the ending of the DMA operation) operation.

I reported below the two pieces of code where the two ticks acquisition are done:

void send_data(void)

{

start=(uint64)IfxStm_get(IFXSTM_DEFAULT_TIMER) & TIME_INFINITE;

IfxAsclin_Asc_write(&g_ascHandle, g_txData, &g_count, TIME_INFINITE); /* Transmit data via TX */

}

 

void prio_DMA(void)

{

stop=(uint64)IfxStm_get(IFXSTM_DEFAULT_TIMER) & TIME_INFINITE;

g_correctTransactions++;

}

7 Replies
FD_aurix
Level 5
Level 5
100 sign-ins 100 replies posted 5 solutions authored

it should be quite accurate but remember always that cache could impact it and also other interrupt (if enbaled).

What is the time you expect , what are the values you get and what is the spread of these values?

0 Likes

Hi @FD_aurix , thanks for your answer. 

I'm transmissiting 5 bytes at 8Mbit/sec so i expect to measure at least 1.25micro seconds for the transmission of one byte(8 bit of data plus the start and stop bit), so, in total, 6.25micro seconds for the transmission. In addition to these 6.25micro seconds i  would have no idea how long the DMA transfer from the hw FIFO to the DSPR might take. 

 

My main problem is that using the example programme https://www.infineon.com/dgdl/Infineon-UART_DMA_Transfer_1_KIT_TC375_LK-Training-v01_00-EN.pdf?fileI..., I should get g_transferCount=12 but I get it =1, which makes me think that the ISR of the end of the DMA movement is only executed once instead of 12 times.

0 Likes

Hi

If you have a debugger (e.g. lauterbach) with trace option this measore will be quite easy.

About your issue probably you are misunderstanding (as I was) the functionality of the DMA. Transaction is different from transfer :-D. In the example there 12 transaction composed by 1 transfer , so each transfer is composed by 1 transaction. 

in the example you linked (if it works... since some of the example are not working!) 

g_correctTransactions should reach 12 at the end of the string transmission

 

g_transferCount is not present in the example but if you are referring to  ( cfg.transferCount = N_TRANSFER;)  this is the selection of the number of transfer for each transaction (1)

0 Likes

Sorry @FD_aurix , I was referring to g_correctTransactions.
What doesn't make sense to me is why the value of that variable is one instead of 12, since it should enter the ISR 12 times.
In any case, it may be that it is a debugger problem. To this end, I am asking if it is possible to print out the value of the variable g_correctTransactions in the terminal using printf. In the past I have tried using printf to get the values of variables to avoid the debugger but I could not figure out where it prints the values.

0 Likes

Hi @Kevingiordano14,

You could be checking before it has time for the transactions. Check for the count until it checks 12, that way you know if it is reaching it or is not doing anything.

Printf prints in the File System Simulation (FSS) View window in Aurix Development Studio, if this doesn’t open when debugging, you can open it in Window -> Show View -> Other and in the search-bar write FSS.

What you could also do is set the UART for a serial communication through the COM port and use the Serial Monitor of Aurix Development Studio, or any of your choosing. For an example check the DMA_ADC_Transfer_1_KIT_TC375_LK.

Best regards,

Erick

Erick_G
Moderator
Moderator
Moderator
100 sign-ins 25 solutions authored 50 replies posted

Hi @Kevingiordano14,

At calculating the time, the values should not be too far apart, but take in account the other reply as well.

You can also use the CPU performance counters. In this thread you can see an example of how to use them with the drivers. Within the iLLD documentation you can find the functions in Modules -> CPU -> Performance Counter Functions.

Also, don’t share documents as is, you should share the link if it is available on the Infineon website. Thank you.

UART_DMA_Transfer_1 for KIT_AURIX_TC375_LK

Best regards,

Erick

0 Likes

Thank you @Erick_G  for your answers.

It is now clearer to me how to measure time.

Returning to my programme, I want to send 5byte data packets via UART.
I currently have the receiver's hw FIFO set to single move mode, so every time a byte is acquired by the FIFO, it triggers the DMA.

I have configured the DMA as follows:

 

void init_dma(void)

{

/* Initialize an instance of IfxDma_Dma_Config with default values */

IfxDma_Dma_Config dmaConfig;

IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);

 

/* Initialize module */

IfxDma_Dma dma;

IfxDma_Dma_initModule(&dma, &dmaConfig);

 

/* Initial configuration for all channels */

IfxDma_Dma_ChannelConfig cfg;

IfxDma_Dma_initChannelConfig(&cfg, &dma);

 

/* Following configuration is used by the DMA channel */

cfg.transferCount = 1;

cfg.moveSize = IfxDma_ChannelMoveSize_8bit;

cfg.blockMode = IfxDma_ChannelMove_1;

 

/* DMA completes a full transaction on requests */

cfg.requestMode = IfxDma_ChannelRequestMode_completeTransactionPerRequest;

 

/* DMA as Interrupt Service Provider */

cfg.hardwareRequestEnabled = TRUE;

 

/* DMA channel stays enabled after one request */

cfg.operationMode = IfxDma_ChannelOperationMode_continuous;

 

 

/*************** Source and destination addresses ***************/

 

/* Source address is not modified after a transfer */

cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none;

 

/* The element to transfer is always at the same location */

cfg.sourceCircularBufferEnabled = TRUE;

cfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; //dopo ogni transaction, l'indirizzo aumenta di 1

 

/* Copy the elements sequentially next to each others */

cfg.destinationCircularBufferEnabled = FALSE;

 

 

/*************** Channel specific configurations ***************/

 

/* Select the Channel 12, related to the interruption on AscLin RX */

cfg.channelId = (IfxDma_ChannelId) DMA_CHANNEL;

 

/* Address of the UART RX FIFO */

cfg.sourceAddress = (uint32) &g_ascHandle.asclin->RXDATA.U;

 

/* Address of DLMU0 */

cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &RxBuffer[0]); // move into result buffer;

cfg.channelInterruptEnabled = TRUE;

 

/* DMA triggers an interrupt once the full transaction is done */

cfg.channelInterruptControl = IfxDma_ChannelInterruptControl_thresholdLimitMatch;

 

/* Priority of the channel interrupt trigger */

cfg.channelInterruptPriority = INTPRIO_DMA;

 

/* Interrupt service provider */

cfg.channelInterruptTypeOfService = IfxSrc_Tos_cpu0;

 

/* Initialize the DMA channel */

IfxDma_Dma_initChannel(&g_chn, &cfg);

}

 

I expect that, as it is configured in IfxDma_ChannelRequestMode_completeTransactionPerRequest, each byte received from the fifo will trigger a transaction consisting of a transfer making an 8-bit move.
Furthermore, as cfg.channelInterruptControl is configured = IfxDma_ChannelInterruptControl_thresholdLimitMatch; I expect that at the end of each transaction, an interrupt is generated.

I would like to ask if my assumptions are correct, since then, once the code is executed, the programme enters the DMA's end-of-transaction ISR only after the 5bytes have been transferred from the DMA.

 

0 Likes