problem DMA S32K1 HardFault

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

problem DMA S32K1 HardFault

1,667 Views
michelet1
Contributor II

Good morning everyone,

I'm trying to implement DMA on the k1 to then be able to link the ADC results to it.

I tried to configure the DMA registers as follows:

 

 

void DMA_Init(void)
{
uint8_t i = 0;

//just for safe, for configuration deactive DMA channel on CSR register:
DMA->TCD->CSR &= !DMA_TCD_CSR_ACTIVE_MASK; //put 0 on ACTIVE bitof CSR register

//1. Write to the CR if a configuration other than the default is desired.
DMA->CR = DMA_CR_EMLM(1)|DMA_CR_ERCA(1);//enable minor loop. use round robin prior

for (i = 0; i<DMAD_CHAN_NMB; i++) //cicla su tutti i canali di DMA usati
{
// 4. Write the 32-byte TCD for each channel that may request service.
// 4.1 Source ADDRESS:
DMA->TCD->SADDR = DMAD_CfgTable[i].SourceAddr;

// 4.2 Source ADDRESS OFFSET:
DMA->TCD->SOFF = DMA_TCD_SOFF_SOFF(0); //proviamo a usare un offset 0

// 4.3 Transfer Attributes, SMOD, SSIZE, DMOD, DSIZE:
DMA->TCD->ATTR =
DMA_TCD_ATTR_SMOD(0) |
DMA_TCD_ATTR_SSIZE(0x2) | //0x2 = 010b -> 32-bit //TODO ROR: mettere in tabella di config
DMA_TCD_ATTR_DMOD(0) |
DMA_TCD_ATTR_DSIZE(0x2) ; //0x2 = 010b -> 32-bit //TODO ROR: mettere in tabella di config

// 4.4 Minor Byte Count, Signed Minor Loop Offset N, Signed Minor Loop Offset Y:
DMA->TCD->NBYTES.MLNO = DMA_TCD_NBYTES_MLNO_NBYTES(0x4); //proviamo a usare 4 byte

// 4.5 Last Source Address Adjustment:
DMA->TCD->SLAST = 0x0; //proviamo a usare un adjustment di 0

// 4.6 Destination Address:
DMA->TCD->DADDR = DMAD_CfgTable[i].DestinAddr;

// 4.7 Signed Destination Address Offset:
DMA->TCD->DOFF = DMA_TCD_DOFF_DOFF(0); //proviamo a usare un offset 0


// 4.9 Last Destination Address Adjustment/Scatter Gather Address :
DMA->TCD->DLASTSGA = 0x0; //proviamo a usare un adjustment di 0


// 4.11 Beginning Minor Loop Link, Major Loop Count, Beginning Minor Loop Link, Major Loop Count:
DMA->TCD->BITER.ELINKNO = 0x0001; //test wit channel-to-channel linking disable 0x0001
DMA->TCD->BITER.ELINKYES = 0x0001; //test wit channel-to-channel linking disable 0x0001
}

// 5. Enable any hardware service requests via the ERQ register.
DMA->ERQ = 0x00000000; //all disabled at the moment

// 6. Request channel service via either:
// - Software: setting the TCDn_CSR[START]
// - Hardware: slave device asserting its eDMA peripheral request signal
for (i = 0; i<DMAD_CHAN_NMB; i++) //cicla su tutti i canali usati di DMA
{
//Set START and ACTIVE on Control and Status:
DMA->TCD->CSR = DMA_TCD_CSR_START(1) | DMA_TCD_CSR_ACTIVE(1);
}

//Activate DMA:
DMA->CR = DMA_CR_ACTIVE(1);//eDMA is executing a channel

}

 

In debug a problem is generated(HardFault) as soon as we execute DMA->TCD->CSR = DMA_TCD_CSR_START(1) | DMA_TCD_CSR_ACTIVE(1); 

 

The initialization configuration seems correct even studying the S32K-RM manual reference. are there any registers missing to configure? any help/advice is welcome. thanks in advance

 

0 Kudos
Reply
5 Replies

1,652 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @michelet1,

What kind of fault exception is it?

Can you read the Configurable Fault Status Register (CFSR)?

https://community.nxp.com/t5/S32K-Knowledge-Base/Fault-handling-on-S32K14x/ta-p/1114447

By the way, TCD0_CSR - TCD15_CSR[ACTIVE] is read-only, you should not write there.

 

Regards,

Daniel

 

0 Kudos
Reply

1,582 Views
michelet1
Contributor II

Thanks for the reply.

I managed to solved the problem by looking at the link you indicated.

i also consulted the AN5413 codebook which contains DMA example. At the moment i have implemented a basic example in which i fill a starting buffer with values set by me(without any connection to external peripherals) and i find them in the destination buffer. 

In this regard i have a doubt........if i have a uint8_t buffer[8] and i want to change the values only of buffer[0],buffer[1],buffer[2],  do i have to call the following steps via software?

step to repeat each time to find value in destination buffers ?? :

DMA->SSRT = 0; /* Set chan 0 START bit to initiate first minor loop */


while ( ((DMA->TCD[0].CSR >> DMA_TCD_CSR_START_SHIFT) & 1) | ((DMA->TCD[0].CSR >> DMA_TCD_CSR_ACTIVE_SHIFT) & 1) )
{
/* Wait for START=0 and ACTIVE=0 */
}


/* Now minor loop has completed */


while (!((DMA->TCD[0].CSR >> DMA_TCD_CSR_DONE_SHIFT) & 1) ) /* Loop till DONE = 1 */
{

/* Place breakpoint at next instruction & observe expressions TCD0_Source, TCD0_Dest */
DMA->SSRT = 0; /* Set chan 0 START bit to initiate next minor loop */

while ( ((DMA->TCD[0].CSR >> DMA_TCD_CSR_START_SHIFT) & 1) | ((DMA->TCD[0].CSR >> DMA_TCD_CSR_ACTIVE_SHIFT) & 1) )
{
/* Wait for START=0 and ACTIVE=0 */
}


/* Now minor loop has completed */


}


DMA->TCD[0].CSR &= ~(DMA_TCD_CSR_DONE_MASK); /* Clear DONE bit */

thanks again for your help.

best regards

 

0 Kudos
Reply

1,573 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @michelet1,

I have difficulties to understand, can you please elaborate on the description of the use case?

 

0 Kudos
Reply

1,560 Views
michelet1
Contributor II

Hello,

maybe i explained myself badly but rereading the following lines of the codebook maybe i already answered myself:

"Because a peripheral is not involved in this example, automatic DMA handshaking will not occur. Instead,
the software handshaking given here must be implemented for each DMA request (minor loop transfer):
• Start DMA service request (set a START bit for desired channel).
• Wait for the minor loop transfer to complete by polling for START and ACTIVE status.
• Repeat above two steps until major loop is complete as indicated by DONE bit
These steps appear “messy” for every transfer, which is only a byte in this example. However, when using
actual peripherals, software never has to do these steps; they are done automatically by hardware."

 

In the case i want to exchange data from a source to a destination via DMA but the source is not a peripheral(ADC,etc...) i must necessarily manage the exchange mechanism via SW by managing the DONE,ACTIVE,START bits.  is that correct?

thanks again for your availability

 

 

0 Kudos
Reply

1,500 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @michelet1,

Even if both the source and the destination are in SRAM, you can still use HW to trigger the transfers and have an interrupt at the end of the major loop.

Refer to S32K1xx_DMA_Interrupt_mapping.xlsx attached to the RM.

 

 

 

 

0 Kudos
Reply