I have an FPGA connected to the GPMC on a am3359. I've set it up as I think it should be, but whenever I try to write to the FPGA, I always get data abort.
Here are my settings, largely copied from the 1641 GPMC DRAM Example floating around these forums:
unsigned int GPMCPinMuxSetup(void)
{
MUX_VAL(CONTROL_PADCONF_GPMC_AD0, (IEN | PD | MODE0 )) /* GPMC_AD0 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD1, (IEN | PD | MODE0 )) /* GPMC_AD1 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD2, (IEN | PD | MODE0 )) /* GPMC_AD2 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD3, (IEN | PD | MODE0 )) /* GPMC_AD3 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD4, (IEN | PD | MODE0 )) /* GPMC_AD4 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD5, (IEN | PD | MODE0 )) /* GPMC_AD5 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD6, (IEN | PD | MODE0 )) /* GPMC_AD6 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD7, (IEN | PD | MODE0 )) /* GPMC_AD7 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD8, (IEN | PD | MODE0 )) /* GPMC_AD8 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD9, (IEN | PD | MODE0 )) /* GPMC_AD9 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD10, (IEN | PD | MODE0 )) /* GPMC_AD10 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD11, (IEN | PD | MODE0 )) /* GPMC_AD11 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD12, (IEN | PD | MODE0 )) /* GPMC_AD12 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD13, (IEN | PD | MODE0 )) /* GPMC_AD13 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD14, (IEN | PD | MODE0 )) /* GPMC_AD14 */;
MUX_VAL(CONTROL_PADCONF_GPMC_AD15, (IEN | PD | MODE0 )) /* GPMC_AD15 */;
MUX_VAL(CONTROL_PADCONF_GPMC_A0, (IEN | PD | MODE0 )) /* GPIO1[16] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A1, (IEN | PD | MODE0 )) /* GPIO1[17] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A2, (IEN | PD | MODE0 )) /* GPIO1[18] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A3, (IEN | PD | MODE0 )) /* GPIO1[19] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A4, (IEN | PD | MODE0 )) /* GPIO1[20] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A5, (IEN | PD | MODE0 )) /* GPIO1[21] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A6, (IEN | PD | MODE0 )) /* GPIO1[22] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A7, (IEN | PD | MODE0 )) /* GPIO1[23] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A8, (IEN | PD | MODE0 )) /* GPIO1[24] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A9, (IEN | PD | MODE0 )) /* GPIO1[25] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A10, (IEN | PD | MODE0 )) /* GPIO1[26] */;
MUX_VAL(CONTROL_PADCONF_GPMC_A11, (IEN | PD | MODE0 )) /* GPIO1[27] */;
MUX_VAL(CONTROL_PADCONF_GPMC_CSN1, (IEN | PU | MODE0 )) /* GPMC_CLK_MUX1 */;
MUX_VAL(CONTROL_PADCONF_GPMC_ADVN_ALE, (IDIS | PU | MODE0 )) /* GPMC_ADVN_ALE */;
MUX_VAL(CONTROL_PADCONF_GPMC_OEN_REN, (IDIS | PU | MODE0 )) /* GPMC_OEN_REN */;
MUX_VAL(CONTROL_PADCONF_GPMC_WEN, (IDIS | PU | MODE0 )) /* GPMC_WEN */;
//upper address lines are on mode 1
MUX_VAL(CONTROL_PADCONF_LCD_DATA8, (IEN | PD | MODE1 )) /* GPIO2[14] */;
MUX_VAL(CONTROL_PADCONF_LCD_DATA9, (IEN | PD | MODE1 )) /* GPIO2[15] */;
MUX_VAL(CONTROL_PADCONF_LCD_DATA10, (IEN | PD | MODE1 )) /* GPIO2[16] */;
MUX_VAL(CONTROL_PADCONF_LCD_DATA11, (IEN | PD | MODE1 )) /* GPIO2[17] */;
MUX_VAL(CONTROL_PADCONF_LCD_DATA12, (IEN | PD | MODE1 )) /* GPIO0[8] */;
MUX_VAL(CONTROL_PADCONF_LCD_DATA13, (IEN | PD | MODE1 )) /* GPIO0[9] */;
MUX_VAL(CONTROL_PADCONF_LCD_DATA14, (IEN | PD | MODE1 )) /* GPIO0[10] */;
MUX_VAL(CONTROL_PADCONF_LCD_DATA15, (IEN | PD | MODE1 )) /* GPIO0[11] */;
MUX_VAL(CONTROL_PADCONF_MMC0_DAT3, (IEN | PD | MODE1 )) /* GPIO2[26] */;
MUX_VAL(CONTROL_PADCONF_MMC0_DAT2, (IEN | PD | MODE1 )) /* GPIO2[27] */;
MUX_VAL(CONTROL_PADCONF_MMC0_DAT1, (IEN | PD | MODE1 )) /* GPIO2[28] */;
MUX_VAL(CONTROL_PADCONF_MMC0_DAT0, (IEN | PD | MODE1 )) /* GPIO2[29] */;
MUX_VAL(CONTROL_PADCONF_MMC0_CLK, (IEN | PD | MODE1 )) /* GPIO2[30] */;
MUX_VAL(CONTROL_PADCONF_MMC0_CMD, (IEN | PD | MODE1 )) /* GPIO2[31] */;
}
void GPMC_CONFIG_Settings(void)
{
int fpgaCS = 1;
unsigned int temp;
//enable clock to GPMC module
HWREG(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL ) |=
CM_PER_GPMC_CLKCTRL_MODULEMODE_ENABLE;
//check to see if enabled
while((HWREG(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL) & CM_PER_GPMC_CLKCTRL_IDLEST) !=
(CM_PER_GPMC_CLKCTRL_IDLEST_FUNC << CM_PER_GPMC_CLKCTRL_IDLEST_SHIFT));
//reset the GPMC module
HWREG(SOC_GPMC_0_REGS + GPMC_SYSCONFIG ) |= GPMC_SYSCONFIG_SOFTRESET;
while((HWREG(SOC_GPMC_0_REGS + GPMC_SYSSTATUS) & GPMC_SYSSTATUS_RESETDONE) ==
GPMC_SYSSTATUS_RESETDONE_RSTONGOING);
//Configure to no idle
temp = HWREG(SOC_GPMC_0_REGS + GPMC_SYSCONFIG);
temp &= ~GPMC_SYSCONFIG_IDLEMODE;
temp |= GPMC_SYSCONFIG_IDLEMODE_NOIDLE << GPMC_SYSCONFIG_IDLEMODE_SHIFT;
HWREG(SOC_GPMC_0_REGS + GPMC_SYSCONFIG) = temp;
HWREG(SOC_GPMC_0_REGS + GPMC_IRQENABLE) = 0x0;
HWREG(SOC_GPMC_0_REGS + GPMC_TIMEOUT_CONTROL) = 0x0;
HWREG(SOC_GPMC_0_REGS + GPMC_CONFIG1(fpgaCS)) = 0x00001000;
HWREG(SOC_GPMC_0_REGS + GPMC_CONFIG2(fpgaCS)) = 0x0007080A;
HWREG(SOC_GPMC_0_REGS + GPMC_CONFIG3(fpgaCS)) = 0;
HWREG(SOC_GPMC_0_REGS + GPMC_CONFIG4(fpgaCS)) = 0x04020702;
HWREG(SOC_GPMC_0_REGS + GPMC_CONFIG5(fpgaCS)) = 0x0009090A;
HWREG(SOC_GPMC_0_REGS + GPMC_CONFIG6(fpgaCS)) = 0;
HWREG(SOC_GPMC_0_REGS + GPMC_CONFIG7(fpgaCS)) = 0x00000F00; //address space starts at 0x10000000
HWREG(SOC_GPMC_0_REGS + GPMC_CONFIG7(fpgaCS)) += 0x00000040; //enable fpga cs
}
void GPMC_Init(void)
{
unsigned int *pmem;
GPMC_CONFIG_Settings();
GPMCPinMuxSetup();
pmem = (unsigned int*) 0x00001000;
*pmem = 123;
}
What am I doing wrong?