EIM in iMX7D in Multiplexed synchronous Read/Write mode

Hi,

I am trying to run the EIM interface in 16 bit Multiplexed synchronous(Burst) mode( to interface EIM with FPGA ). Please find the source code below:

// WEIM clock root and clock gate registers
#define CCM_BASE_ADDRESS    0x30380000
#define CCM_CCGR22          0x30384160
#define CCM_TARGET_ROOT83   0x3038A980
 
/* WEIM registers */
typedef struct
{
    UINT32 EIM_CS0GCR1;
    UINT32 EIM_CS0GCR2;
    UINT32 EIM_CS0RCR1;
    UINT32 EIM_CS0RCR2;
    UINT32 EIM_CS0WCR1;
    UINT32 EIM_CS0WCR2;
    UINT32 EIM_CS1GCR1;
    UINT32 EIM_CS1GCR2;
    UINT32 EIM_CS1RCR1;
    UINT32 EIM_CS1RCR2;
    UINT32 EIM_CS1WCR1;
    UINT32 EIM_CS1WCR2;
    UINT32 EIM_CS2GCR1;
    UINT32 EIM_CS2GCR2;
    UINT32 EIM_CS2RCR1;
    UINT32 EIM_CS2RCR2;
    UINT32 EIM_CS2WCR1;
    UINT32 EIM_CS2WCR2;
    UINT32 EIM_CS3GCR1;
    UINT32 EIM_CS3GCR2;
    UINT32 EIM_CS3RCR1;
    UINT32 EIM_CS3RCR2;
    UINT32 EIM_CS3WCR1;
    UINT32 EIM_CS3WCR2;
    UINT32 EIM_CS4GCR1;
    UINT32 EIM_CS4GCR2;
    UINT32 EIM_CS4RCR1;
    UINT32 EIM_CS4RCR2;
    UINT32 EIM_CS4WCR1;
    UINT32 EIM_CS4WCR2;
    UINT32 EIM_CS5GCR1;
    UINT32 EIM_CS5GCR2;
    UINT32 EIM_CS5RCR1;
    UINT32 EIM_CS5RCR2;
    UINT32 EIM_CS5WCR1;
    UINT32 EIM_CS5WCR2;
    UINT32 EIM_WCR;
    UINT32 EIM_DCR;
    UINT32 EIM_DSR;
    UINT32 EIM_WIAR;
    UINT32 EIM_EAR;
}tEIM_CSP_WEIM_REGS, *ptEIM_CSP_WEIM_REGS;
 
//-----------------------------------------------------------------------------
// Configure the IOs for the iMX7 EIM bus
/// @param[in] hGpio    handle received from Gpio_Init()
/// @retval     TRUE       Success
/// @retval     FALSE      Failure
BOOL Eim_ConfigureIos(HANDLE hGpio)
{
    int i;
    BOOL fSuccess = TRUE;
 
    const uIo eimIo[] =
    {
        COLIBRI_PIN( 89),   // RW
        COLIBRI_PIN( 91),   // OE
        COLIBRI_PIN(105),   // CS0_B
        COLIBRI_PIN(150),   // LBA_B
        COLIBRI_PIN(152),   // BCLK
        COLIBRI_PIN(111),   // AD0
        COLIBRI_PIN(113),   // AD1
        COLIBRI_PIN(115),   // AD2
        COLIBRI_PIN(117),   // AD3
        COLIBRI_PIN(119),   // AD4
        COLIBRI_PIN(121),   // AD5
        COLIBRI_PIN(123),   // AD6
        COLIBRI_PIN(125),   // AD7
        COLIBRI_PIN(110),   // AD8
        COLIBRI_PIN(112),   // AD9
        COLIBRI_PIN(114),   // AD10
        COLIBRI_PIN(116),   // AD11
        COLIBRI_PIN(118),   // AD12
        COLIBRI_PIN(120),   // AD13
        COLIBRI_PIN(122),   // AD14
        COLIBRI_PIN(124)    // AD15
    };
 
    /// The EIM functionality is on Alternate Function 4 for all EIM pins.
    for (i = 0; i < _countof(eimIo); i++)
        fSuccess &= Imx7Gpio_SetConfigString(hGpio, eimIo[i], NULL, L"AltFn=4", StoreVolatile);
 
    return fSuccess;
}
 
//*****************************************************************************
/// Main function
/// @param[in]  argc    number of command line arguments
/// @param[in]  argv    array containing command line arguments
/// @retval     1       Success
/// @retval     0       Failure
int wmain(int argc, _TCHAR* argv[])
{
    BOOL   fSuccess = TRUE;
    HANDLE hMap;
    HANDLE hGpio;
 
    volatile ptEIM_CSP_WEIM_REGS pEimReg;
    volatile DWORD *clkRegs;
    volatile DWORD  tmp;
    volatile UINT16 *extBus;
    volatile DWORD *targetAddr;
    UINT16 i;

	UINT16 buff[ ] = { 0xAA,0x11,0x22,0x77,0x33,0x44,0x55,0x66 };
 
    // Enable EIM Clock, 
    hMap = Map_Init();
    clkRegs  = (DWORD* )Map_MapMemory(CCM_BASE_ADDRESS, 0x10000);
    targetAddr =  clkRegs + (CCM_CCGR22 - CCM_BASE_ADDRESS)/4;
    *targetAddr &= ~0xFFFFFFFF;
    targetAddr = clkRegs + (CCM_TARGET_ROOT83 - CCM_BASE_ADDRESS)/4;
    *targetAddr |= 0x16030000;    //  125MHz/4
    targetAddr = clkRegs + (CCM_CCGR22 - CCM_BASE_ADDRESS)/4;
    *targetAddr |= 0x03;
 
    // configure EIM GPIOs
    hGpio = Imx7Gpio_Init(NULL);
    fSuccess &= Eim_ConfigureIos(hGpio);
    fSuccess &= Imx7Gpio_Deinit(hGpio);
 
    // Configure CS0 properties for multiplexed, asynchronous operation
    pEimReg = (ptEIM_CSP_WEIM_REGS)Map_MapMemory(0x30BC0000, 0x1000); 


	pEimReg->EIM_WIAR &=	~( 1 << 4 );

	pEimReg->EIM_CS0GCR1 = 0x0011013F;  
	pEimReg->EIM_CS0GCR2 = 0x00001000;  
	pEimReg->EIM_CS0RCR1 = 0x01000000; 
	pEimReg->EIM_CS0RCR2 = 0x00000000;  
	pEimReg->EIM_CS0WCR1 = 0x01000000;  
	pEimReg->EIM_CS0WCR2 = 0x00000000;	

	pEimReg->EIM_WCR |=		( 1 << 3 );

	pEimReg->EIM_WIAR |=	( 1 << 4 );




    printf("CSxGCR1 main reg: 0x%08X\n",pEimReg->EIM_CS0GCR1);
    printf("CSxGCR2 main reg: 0x%08X\n",pEimReg->EIM_CS0GCR2);
    printf("CSxRCR1 main reg: 0x%08X\n",pEimReg->EIM_CS0RCR1);
    printf("CSxRCR2 main reg: 0x%08X\n",pEimReg->EIM_CS0RCR2);
    printf("CSxWCR1 main reg: 0x%08X\n",pEimReg->EIM_CS0WCR1);
    printf("CSxWCR2 main reg: 0x%08X\n",pEimReg->EIM_CS0WCR2);
	printf("WCR main reg: 0x%08X\n",pEimReg->EIM_WCR);

	printf("WIAR main reg: 0x%08X\n",pEimReg->EIM_WIAR);
	printf("DCR main reg: 0x%08X\n",pEimReg->EIM_DCR);
	printf("DSR main reg: 0x%08X\n",pEimReg->EIM_DSR);
 
 
    // Access memory at CS0 address.
    // The address range for nCS0 is 0x28000000 to 0x28FFFFFF (128MB).
    // However, we map only 64kB here.
    extBus =(UINT16* )Map_MapMemory(0x28000000, 0x5000);
	
	while(1)
	{	

		memcpy( (UINT16*)extBus, buff, sizeof( buff ) );		
	
	}
 
    return 1;
}

As per my understanding when using burst mode with every address assertion an address and then a burst of data(8 Words in my case) will be sent on EIM bus and then process repeats as I am running a while loop. However this is not a happening in my case. I am not able to see this behaviour. Data is not coming in burst and Address, CS and RW signals are not as per configuration.

There are few queries for better understanding of the interface:

  1. Is there difference between Synchronous mode and Burst mode ?
  2. Is there any initialisation sequence for continuous BCLK Multiplexed synchronous mode ?
  3. In case of fix latency mode all the wait states are ignored( like WWSC/RWSC) ?
  4. Start address of CS0 is 0x28000000, I haven’t found it in iMX7D reference guide, From where i can find the addresses of all the chip selects ?

Regards
Bipin Kumar

Dear @bipin7301

I’m afraid we don’t have more information than what is documented in the i.MX7 reference manual.

  1. As the reference manual always uses both terms “Burst (Synchronous Mode)” at the same time, I would assume it is the same thing.
  2. I’m not aware of any special initialization required for the burst mode. However, we never tested the details. We just created the basic sample:
    Basic Usage of the External EIM Bus on Colibri iMX7
  3. We never tested this. However, i would expect that wait states are actually used for fix latency mode.
  4. For the CSx configuration, have a look at the description of the IOMUXC-GPR_GPR1 register: Especially the description of Bits 11-10 explain how the 128MB total EIM adress space can be split between the four chip selects.

Regards, Andy