This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

calling IntDisable from a task is causing a hard fault

Other Parts Discussed in Thread: TM4C129ENCPDT

Using TM4C129ENCPDT and Kiel uvision 5.15.0
I'm trying to disable interrupt #66 (call to tivaware/interrupt.c/IntDisable(INT_EPI0)) from withing a task, but I keep getting a hard fault.
If I execute the same code from withing main, the code runs to completion.
Any ideas?
Khaled.

  • Hello Khaled,

    What is the fault type as given in the FAULTSTAT register?

  • Hi Amit,

    Here is the fault register and the NVIC registers.

    Khaled.

  • Hello Khaled

    Since the PRECISE bus fault is triggered and BFARV is also set, check the Bus Fault Address register for the address that has caused the bus fault
  • Hi Amit,
    I'm not sure what you are asking me to do or how to do it. Please elaborate.
    thanks.
    khaled
  • Hello Khaled

    When the Fault Status is set as PRECISE and BFARV is set then the address which caused the Bus Fault is registered in FAULTADDR register
  • Hi Amit,
    The address is 0xE000E184 which point to nothing: no code section nor a data section.
    The problem has to do with the sequence of command that I use to put the EPI registers into a default know values before re-initialize the interface.
    Indeed, in order to test my EPI recovery code, I forced a error on the EPI interface and then I tried to set the interface registers to default starting value before I configure them anew.

    The code that I use to put the registers into a know default values is below

    IntDisable( INT_EPI0); //this instruction causes a hard fault
    IntPendClear( INT_EPI0);
    EPIIntDisable( EPI0_BASE, 0xFF);
    EPIIntErrorClear( EPI0_BASE, 0xFF);

    // Put the attributes in a known state for the uDMA EPI channel.
    uDMADisable();
    uDMAIntClear( UDMA_CH20_EPI0RX);
    uDMAIntClear( UDMA_CH21_EPI0TX);

    uDMAChannelDisable( UDMA_CH20_EPI0RX);
    uDMAChannelDisable( UDMA_CH21_EPI0TX);

    uDMAChannelAttributeDisable(UDMA_CH20_EPI0RX, UDMA_ATTR_ALL); //this instruction causes a hard fault as well
    uDMAChannelAttributeDisable(UDMA_CH21_EPI0TX, UDMA_ATTR_ALL);
    uDMAChannelControlSet( UDMA_CH20_EPI0RX, UDMA_DST_INC_NONE | UDMA_SRC_INC_NONE);
    uDMAChannelControlSet( UDMA_CH21_EPI0TX, UDMA_DST_INC_NONE | UDMA_SRC_INC_NONE);

    Khaled.
  • Hello Khaled,

    My 2 cents on the fact the FAULTADDR register at 0xE000ED38 will have the address of EPI register....
  • Amit
    found it. Its the NVIC register/DIS1 Interrupt32-63 clear enable.
    But it brings nothing new, since I already know that the hardfault is caused by the IntDisable( INT_EPI0) (see code in the previous post of Sept 6th)
    The question, is why? and do I fix it?
    Khaled.
  • Hello Khaled

    First clear the pending interrupt and then disable the interrupt.
  • Amit,
    Finally some progress :-)
    Swapping the commands solved that EPI hard fault. Thanks.

    Now the hard fault moved to the uDMAChannelControlSet( ) (see post of Sep 6ht).
    My objective is to reset the EPI uDMA registers before re-initializing them.
    Could you please take a look at that code and tell me if the command sequence to reset the uDMA is correct?
    The FAULTADDR is 0xE000EDF8.

    thanks.
    Khaled.
  • Hello Khaled

    I would advise step debug to see what causes the bus fault.Disabling the channel is sufficient to re-init the channel registers which by the way are in SRAM. I normally do not follow the technique you are using, and only update the channel control structures based on the DMA status.
  • Amit,

    I did step into the code and its the uDMAChannelControlSet( ) that is causing the problem.

    I'm stuck at this problem and can't move ahead.

    The system which includes the Cortex and a TM320C6472 is detecting an EPI data error.

    The only way that I know to correct for this error is to reset all the registers (EPI & uDMA) and call my EPI init function and the EPI_uDMA init function again

    void EPI_Init(void) {
    	uint16_t status;
    	 int16_t count;
    
    	//-------------------------------------------------------------
    	// Disable all
    	//-------------------------------------------------------------
    	// Set pointer to EPI memory mapped window.
    	g_pusEPIFPGA = (uint16_t *)0xC0000000;
    
    	//clear the FIFO interrupt triggers
    	IntPendClear(		INT_EPI0);
    	IntDisable( 		INT_EPI0);
    	EPIIntErrorClear(	EPI0_BASE, 0xFF);
    	EPIIntDisable(		EPI0_BASE, 0xFF);
    
    	// Put the attributes in a known state for the uDMA EPI channel.
    	uDMAIntClear(		UDMA_CH20_EPI0RX);
    	uDMAIntClear(		UDMA_CH21_EPI0TX);
    	uDMADisable();
    
    	uDMAChannelDisable(	UDMA_CH20_EPI0RX);
    	uDMAChannelDisable(	UDMA_CH21_EPI0TX);
    
    	uDMAChannelAttributeDisable(UDMA_CH20_EPI0RX, UDMA_ATTR_ALL);
    	uDMAChannelAttributeDisable(UDMA_CH21_EPI0TX, UDMA_ATTR_ALL);
    
    	uDMAChannelControlSet(UDMA_CH20_EPI0RX, UDMA_DST_INC_NONE | UDMA_SRC_INC_NONE);
    	uDMAChannelControlSet(UDMA_CH21_EPI0TX, UDMA_DST_INC_NONE | UDMA_SRC_INC_NONE);
    
    
    	//-------------------------------------------------------------
    	// Configure the EPI interface
    	//  - speed
    	//  - operation mode
    	//  - configuration registers
    	//-------------------------------------------------------------
    	//disable EPI
    	EPIModeSet(		EPI0_BASE,
    					EPI_MODE_DISABLE);
    	EPIDividerSet(	EPI0_BASE,
    					EPI_DIV_FACTOR_DATA);
    	EPIModeSet(		EPI0_BASE,
    					EPI_MODE_HB16);
        EPIConfigHB16Set(EPI0_BASE,
    //					EPI_HB16_USE_TXEMPTY          |		//Tx fifo empty enable
    //					EPI_HB16_USE_RXFULL           |		//Rx fifo full enable
    //					EPI_HB16_BURST_TRAFFIC        | 	//burst mode enabled
    					EPI_HB16_IN_READY_EN          |  	//IRDY enabled
    					EPI_HB16_IN_READY_EN_INVERTED |		//IRDY polarity inverted
    					EPI_HB16_MODE_ADDEMUX         | 	//sets up data and address as separate
    					EPI_HB16_CSCFG_ALE            |		//EPIS030 to operate as an address latch (ALE)
    					EPI_HB16_ALE_HIGH             |		//sets the address latch active high
    					EPI_HB16_WRWAIT_0             |		//sets write wait state to 2 EPI clocks.
    					EPI_HB16_RDWAIT_0             , 	//sets read wait state to 2 EPI clocks.
    					0xF0);								//FIFO mode	maximum number of clocks
    	EPIConfigHB16TimingSet(EPI0_BASE,
    					0			,						//specifies the chip select to configure[0-3]
    					EPI_HB16_IN_READY_DELAY_1     |   	//sets the stall on input ready (EPIS032)
    														//to start 1 EPI clock after signaled
    					EPI_HB16_WRWAIT_MINUS_ENABLE  |		//enables a 1 EPI clock write wait state reduction
    					EPI_HB16_RDWAIT_MINUS_ENABLE); 		//enables a 1 EPI clock read wait state reduction
    
    	//setup the address mapping for low level driver
    	EPIAddressMapSet(EPI0_BASE,
    					EPI_ADDR_PER_BASE_C   |
    					EPI_ADDR_PER_SIZE_64KB);
    	EPIFIFOConfig(	EPI0_BASE,
    					EPI_FIFO_CONFIG_TX_1_2 |			//2/4 words
    					EPI_FIFO_CONFIG_RX_1_2);			//4/8 words
    
    	//configure the EPI Non blocking read
    	EPINonBlockingReadConfigure(EPI0_BASE,
    					0,
    					EPI_NBCONFIG_SIZE_16,
    					0);
    
    	//-------------------------------------------------------------
    	// Setup the EPI interrupt to service the NBRFIFO and the WFIFO
    	// When the NBRFIFO is full, or the WFIFO is empty generate an
    	// interrupt or trigger a uDMA transfer to service the buffer
    	//-------------------------------------------------------------
    	//setup the interrupt mask for the EPI.
    	//Note: interrupt masking has no effect on uDMA, which
    	//      operates off the raw source of the read/write
    	//      interrupts
    	//Note: we dont want to enable the EPI Rx and Tx interrupt,
    	//      the EPI fifos will be serviced by the uDMA
    	EPIIntEnable(	EPI0_BASE,
    //					EPI_INT_RXREQ       |				//read FIFO above trigger level
    //					EPI_INT_TXREQ       |				//transmit FIFO below trigger level
    					EPI_INT_DMA_TX_DONE |				//transmit DMA completes
    					EPI_INT_DMA_RX_DONE |				//read DMA completes
    					EPI_INT_ERR);						//error condition
    
    	// Enable the EPI interrupt on the processor (NVIC).
    	// Note: even if no EPI interrupt were enabled, the uDMA
    	//       controller will generate an interrupt on the EPI
    	//       interrupt signal when a uDMA transfer is complete.
    	IntEnable(INT_EPI0);
    
    	//-------------------------------------------------------------
    	// Configure the uDMA for the EPI read and write
    	// Make sure the uDMA is configure before calling those functions
    	// i.e. call A_uDMA.c/uDMA_init( ).
    	//-------------------------------------------------------------
    	// Put the attributes in a known state for the uDMA EPI channel.
    	uDMAChannelAssign(UDMA_CH20_EPI0RX);
    	uDMAChannelAssign(UDMA_CH21_EPI0TX);
    
    	// Set the USEBURST attribute for the uDMA EPI RX/TX channel.
    	// and allow the peripheral to generate software request for uDMA channel
    	uDMAChannelAttributeEnable(	UDMA_CH20_EPI0RX,			//NBRFIFO
    								UDMA_ATTR_USEBURST       |	//single request is not supported
    								UDMA_ATTR_HIGH_PRIORITY);	//needed for ADC transfers
    	uDMAChannelAttributeEnable(	UDMA_CH21_EPI0TX,			//WFIFO
    								UDMA_ATTR_USEBURST);		//single request is not supported
    
    	// Configure the control parameters for the EPI RX/TX.  The uDMA EPI RX/TX
    	uDMAChannelControlSet(		UDMA_CH20_EPI0RX,			//NBRFIFO
    								UDMA_SIZE_16       |		//data size
    								UDMA_SRC_INC_NONE  |		//no source address increment
    								UDMA_DST_INC_16    |		//destination address increment
    								UDMA_ARB_4);				//arbitration size
    	uDMAChannelControlSet(		UDMA_CH21_EPI0TX,			//WFIFO
    								UDMA_SIZE_16       |		//data size
    								UDMA_SRC_INC_16    |		//source address increment
    								UDMA_DST_INC_16    |		//destination address increment
    								UDMA_ARB_2);				//arbitration size
    	uDMAEnable();
    }
    
    .

    I'm open for suggestions.

    If you recommand that I can bypass the reset off all registers and go directly to the initialization functions, I will do it.

    Please advise.

    Khaled.

  • Hello Khaled

    You would need to debug the uDMAChannelControlSet function, if it indeed is the cause, by doing step debug, finding the ASM code which causes the issue and correspond it to the C implementation of the function. If the FAULTSTAT does not show any error bit and FAULTADDR does not capture any address on which error is occurring, there is not much I can help out with.
  • Hi Amit
    I think I found a solution: If I wait until the uDMA is done, then I re-initialize the uDMA struct, I don't get the hard fault error anymore.
    lesson learned, resetting the struct while a transfer is in progress is to be avoided.
    Khaled.
  • Hi Amit,
    Correction to the previous post.
    I did add a wait for uDMA done, but I don't think that it was the code change that got me past the hardfault error.
    Looking more at the code, I found that I had a single call to IntMasterDisable( ) and a double calls to IntMasterEnable( ).
    The double call to call to IntMasterEnable( ) seems to be the root of the problem.
    Khaled.
  • Hello Khaled

    That should not cause a bus fault. If the bit is already set, setting it again does not affect Cortex M4 CPU core.
  • In this case I'm at lost at why its working now. Those were the only changes that I have made.
    I'm not complaining but if neither one of those two is the solution, that means that the problem is still there waiting to resurface ! From experience its going to come back to haunt me later.

    Khaled.
  • Hello Khaled

    You mentioned in a previous post, that the control structure was being updated when it was transferring. It may be possible, that it is still the case. Did you check the same by first check if the channel is DONE, then disabling the channel when performing reconfiguration and then enable the same.
  • Amit,

    Yes i did check it and it's not DONE.Even after I wait for some time.

    Usually one of the two don't finish: 1) uDMAChannelModeGet( ) don't stop or 2) uDMAChannelIsEnabled( ) returns true.

    After some wait time, I have no choice but to try and reset the uDMA. This is when the hardfault occurs.


    Khaled.
  • Hello Khaled

    Did you check if there is a DMA error condition set in the DMA register for Error condition?
  • Hi Amit,

    It did not occur to me to check the DMA register :-(

    Since its working now, I need to keep going and finalize next week software release.

    If I have time, I will go back to it after that.

    Khaled.