Debug_SDRAM.ini HardFault

Hi

I asked a similar Q a couple of years back and never got around to working on this again.  Lockdown is letting me circle back to parked issues.....

Now that I have implemented this I am getting a HardFault as soon as I step in debug mode: I get an IACCVIOL and sit on HardFault.  My MPU is not enabled. 

Anyone have any idea?  I have compared to what others have done (but there is not a lot for STM32F4/related) and don't see what I am missing.

  1. simple project attached
  2. MPU shown in attached
  3. FAULT shown in attached
  4. debug init file pasted below (obviously is for my board)
  5. FMC set up is proven to work on this PCBA: I use it in various projects where the SDRAM is used for vars (the same code being implemented within SystemInit_ExtMem)
  6. debug script loader works: I can see it in a memory window
  7. SP and PC are loaded at the correct address as I can see this before I hit the Step button

Thanks (& Happy New Year, 2021, an odd year for another odd experience, thanks Covid)

FUNC void FMC_Wait (void) {
	unsigned int long tmp;
	unsigned int long tmpreg;
	unsigned int long timeout;

	tmp = _RDWORD( 0xA0000158 );
	tmpreg = tmp & 0x00000020; 
	timeout = 0xFFFF;
	while((tmpreg != 0) && (timeout-- > 0))
	{
	  tmp = _RDWORD( 0xA0000158 );
	  tmpreg = tmp & 0x00000020; 
	}
}

FUNC void SetupFMC (void) {
	unsigned int long tmp;
	
	//set GPIO for ExtMem
	tmp = _RDWORD ( 0x40023830 );
	tmp = tmp | 0x000001FF;
	_WDWORD( 0x40023830, 0x000001FF );
	tmp = _RDWORD( 0x40023830 );

	_WDWORD( 0x40020420  , 0x0C000000 );
	_WDWORD( 0x40020424  , 0x00000000 );
	_WDWORD( 0x40020400  , 0x00002000 );
	_WDWORD( 0x40020408  , 0x00002000 );
	_WDWORD( 0x40020404  , 0x00000000 );
	_WDWORD( 0x4002040C  , 0x00000000 );
		
	_WDWORD( 0x40020C20  , 0xCCCC00CC );
	_WDWORD( 0x40020C24  , 0xCCCCCCCC );
	_WDWORD( 0x40020C00  , 0xAAAAAA0A );
	_WDWORD( 0x40020C08  , 0xAAAAAA0A );
	_WDWORD( 0x40020C04  , 0x00000000 );
	_WDWORD( 0x40020C0C  , 0x00000000 );
	
	//GPIOE
	_WDWORD( 0x40021020  , 0xCCCCCCCC );
	_WDWORD( 0x40021024  , 0xCCCCCCCC );
	_WDWORD( 0x40021000  , 0xAAAAAAAA );
	_WDWORD( 0x40021008  , 0xAAAAAAAA );
	_WDWORD( 0x40021004  , 0x00000000 );
	_WDWORD( 0x4002100C  , 0x00000000 );
		
	//GPIOF
	_WDWORD( 0x40021420  , 0x00CCCCCC );
	_WDWORD( 0x40021424  , 0xCCCCC000 );
	_WDWORD( 0x40021400  , 0xAA800AAA );
	_WDWORD( 0x40021408  , 0xAA800AAA );
	_WDWORD( 0x40021404  , 0x00000000 );
	_WDWORD( 0x4002140C  , 0x00000000 );
		
	//GPIOG
	_WDWORD( 0x40021820  , 0x00CCCCCC );
	_WDWORD( 0x40021824  , 0xC0C0000C );
	_WDWORD( 0x40021800  , 0x88020AAA );
	_WDWORD( 0x40021808  , 0x88020AAA );
	_WDWORD( 0x40021804  , 0x00000000 );
	_WDWORD( 0x4002180C  , 0x00000000 );
		
	//GPIOH
	_WDWORD( 0x40021C20  , 0xC0C00000 );
	_WDWORD( 0x40021C24  , 0x00000000 );
	_WDWORD( 0x40021C00  , 0x00008800 );
	_WDWORD( 0x40021C08  , 0x00008800 );
	_WDWORD( 0x40021C04  , 0x00000000 );
	_WDWORD( 0x40021C0C  , 0x00000000 );

  //Enabled FMC Clk
  tmp = _RDWORD ( 0x40023838 );
	_WDWORD( 0x40023838, 0x00000001 );
	tmp = _RDWORD( 0x40023838 );

  //Config FMC
	_WDWORD( 0xA0000140 , 0x000019DA );
	_WDWORD( 0xA0000148 , 0x01115351 );
	_WDWORD( 0xA0000144 , 0x000019DA );
	_WDWORD( 0xA000014C , 0x01115351 );

	_WDWORD( 0xA0000150 , 0x00000009 ); 
	FMC_Wait();

	_WDWORD( 0xA0000150 , 0x0000000A ); 
	FMC_Wait();

	_WDWORD( 0xA0000150 , 0x0000006B ); 
	FMC_Wait();

	_WDWORD( 0xA0000150 , 0x0004600C ); 
	FMC_Wait();

	tmp = _RDWORD( 0xA0000154);
	_WDWORD( 0xA0000154, ( tmp | (0x0000027C<<1)));
	tmp = _RDWORD(0xA0000140);
	_WDWORD( 0xA0000140, ( tmp & 0xFFFFFDFF));
}

FUNC void Setup (void) {
  SP = _RDWORD(0xD3000000);
  PC = _RDWORD(0xD3000004);
  XPSR = 0x01000000;
  _WDWORD(0xE000ED08, 0xD3000000);
}

SetupFMC();
LOAD %L INCREMENTAL
Setup();

//g, main

Debug_SDRAM.rar

  • Eventually I have worked out that, for some reason (Keil IDE?), the MPU is enabled whilst showing as not enabled.  Or, it is an ST issue that is poorly documented.  So, I have added MPU initialisation to my debug.ini script, adding a 4G (full addr area) as Permitted.  Also, I have to init the FPU as I am using RTX and the _init code between startup and main() fails if the FPU is not enabled.

     

    FUNC void FMC_Wait (void) {
    	unsigned int long tmp;
    	unsigned int long tmpreg;
    	unsigned int long timeout;
    
    	tmp = _RDWORD( 0xA0000158 );
    	tmpreg = tmp & 0x00000020; 
    	timeout = 0xFFFF;
    	while((tmpreg != 0) && (timeout-- > 0))
    	{
    	  tmp = _RDWORD( 0xA0000158 );
    	  tmpreg = tmp & 0x00000020; 
    	}
    }
    
    FUNC void SetupFMC (void) {
    	unsigned int long tmp;
    	
    	//set GPIO for ExtMem
    	tmp = _RDWORD ( 0x40023830 );
    	tmp = tmp | 0x000001FF;
    	_WDWORD( 0x40023830, tmp );
    	tmp = _RDWORD( 0x40023830 );
    
    	_WDWORD( 0x40020420  , 0x0C000000 );
    	_WDWORD( 0x40020424  , 0x00000000 );
    	_WDWORD( 0x40020400  , 0x00002000 );
    	_WDWORD( 0x40020408  , 0x00002000 );
    	_WDWORD( 0x40020404  , 0x00000000 );
    	_WDWORD( 0x4002040C  , 0x00000000 );
    		
    	_WDWORD( 0x40020C20  , 0xCCCC00CC );
    	_WDWORD( 0x40020C24  , 0xCCCCCCCC );
    	_WDWORD( 0x40020C00  , 0xAAAAAA0A );
    	_WDWORD( 0x40020C08  , 0xAAAAAA0A );
    	_WDWORD( 0x40020C04  , 0x00000000 );
    	_WDWORD( 0x40020C0C  , 0x00000000 );
    	
    	//GPIOE
    	_WDWORD( 0x40021020  , 0xCCCCCCCC );
    	_WDWORD( 0x40021024  , 0xCCCCCCCC );
    	_WDWORD( 0x40021000  , 0xAAAAAAAA );
    	_WDWORD( 0x40021008  , 0xAAAAAAAA );
    	_WDWORD( 0x40021004  , 0x00000000 );
    	_WDWORD( 0x4002100C  , 0x00000000 );
    		
    	//GPIOF
    	_WDWORD( 0x40021420  , 0x00CCCCCC );
    	_WDWORD( 0x40021424  , 0xCCCCC000 );
    	_WDWORD( 0x40021400  , 0xAA800AAA );
    	_WDWORD( 0x40021408  , 0xAA800AAA );
    	_WDWORD( 0x40021404  , 0x00000000 );
    	_WDWORD( 0x4002140C  , 0x00000000 );
    		
    	//GPIOG
    	_WDWORD( 0x40021820  , 0x00CCCCCC );
    	_WDWORD( 0x40021824  , 0xC0C0000C );
    	_WDWORD( 0x40021800  , 0x88020AAA );
    	_WDWORD( 0x40021808  , 0x88020AAA );
    	_WDWORD( 0x40021804  , 0x00000000 );
    	_WDWORD( 0x4002180C  , 0x00000000 );
    		
    	//GPIOH
    	_WDWORD( 0x40021C20  , 0xC0C00000 );
    	_WDWORD( 0x40021C24  , 0x00000000 );
    	_WDWORD( 0x40021C00  , 0x00008800 );
    	_WDWORD( 0x40021C08  , 0x00008800 );
    	_WDWORD( 0x40021C04  , 0x00000000 );
    	_WDWORD( 0x40021C0C  , 0x00000000 );
    
      //Enabled FMC Clk
      tmp = _RDWORD ( 0x40023838 );
    	_WDWORD( 0x40023838, 0x00000001 );
    	tmp = _RDWORD( 0x40023838 );
    
      //Config FMC
    	_WDWORD( 0xA0000140 , 0x000019DA );
    	_WDWORD( 0xA0000148 , 0x01115351 );
    	_WDWORD( 0xA0000144 , 0x000019DA );
    	_WDWORD( 0xA000014C , 0x01115351 );
    
    	_WDWORD( 0xA0000150 , 0x00000009 ); 
    	FMC_Wait();
    
    	_WDWORD( 0xA0000150 , 0x0000000A ); 
    	FMC_Wait();
    
    	_WDWORD( 0xA0000150 , 0x0000006B ); 
    	FMC_Wait();
    
    	_WDWORD( 0xA0000150 , 0x0004600C ); 
    	FMC_Wait();
    
    	tmp = _RDWORD( 0xA0000154);
    	_WDWORD( 0xA0000154, ( tmp | (0x0000027C<<1)));
    	tmp = _RDWORD(0xA0000140);
    	_WDWORD( 0xA0000140, ( tmp & 0xFFFFFDFF));
    }
    
    FUNC void Setup (void) {
      SP = _RDWORD(0xD3000000);
      PC = _RDWORD(0xD3000004);
      XPSR = 0x01000000;
      _WDWORD(0xE000ED08, 0xD3000000);
    }
    
    FUNC void SetupFPU (void) {
      _WDWORD(0xE000ED88, 0x00F00000);
    }
    
    FUNC void SetupMPU (void) {
    	_WDWORD(0xE000ED90, 0x00000800);
    	_WDWORD(0xE000ED94, 0x00000001);
    
    	_WDWORD(0xE000ED98, 0x00000000);
    	_WDWORD(0xE000ED9C, 0x00000000);
    	_WDWORD(0xE000EDA0, 0x0300003F);
    	_WDWORD(0xE000EDA4, 0x00000000);
    	_WDWORD(0xE000EDA8, 0x0300003F);
    	_WDWORD(0xE000EDAC, 0x00000000);
    	_WDWORD(0xE000EDB0, 0x0300003F);
    	_WDWORD(0xE000EDB4, 0x00000000);
    	_WDWORD(0xE000EDB8, 0x0300003F);
    }
    
    SetupFMC();
    SetupFPU();
    LOAD %L INCREMENTAL
    Setup();
    SetupMPU();
    
    g, main

    I will post the full project as I cannot see where to attach in my reply......

    Mark

More questions in this forum