Other Parts Discussed in Thread: SYSCONFIG, AM3359
Hi,
I'm doing some debugging on SPI transfer between AM3359 (Rev 2.0) and an SPI flash. No I have seen that the SPI0_CS0 signal goes low for a short time doing a reset on the SPI0 module (SOFTRESET on MCSPI_SYSCONFIG). Also there is a glitch on SPI0_CS0 signal after writing to MCSPI_MODULCTRL register). The following screenshot shows the two glitch:
The state of the AM3359 is with SPI0 module already in use after leaving the second level bootloader (StarterWare). Pin SPI0_CS0 is already muxed to SPIEN function at this time. The code of the SPI0 initialization is as follows:
void InitSPI0(void)
{
Uint32 modCtrlReg;
Uint32 chConfReg;
// SPI0 zurücksetzen
HWREG(SOC_SPI_0_REGS+MCSPI_SYSCONFIG)=(HWREG(SOC_SPI_0_REGS+MCSPI_SYSCONFIG) | MCSPI_SYSCONFIG_SOFTRESET);
// Warten, bis SPI0 zurückgesetzt wurde
while(!(HWREG(SOC_SPI_0_REGS+MCSPI_SYSSTATUS) & MCSPI_SYSSTATUS_RESETDONE_COMPLETED));
// Kanal 0 konfigurieren
// Aktueller Stand des Channel 0 Configuration Register lesen
chConfReg=HWREG(SOC_SPI_0_REGS+MCSPI_CHCONF(0));
// Clock Granularität 2^x
chConfReg=(chConfReg & ~MCSPI_CH0CONF_CLKG);
// RX FIFO sperren
chConfReg=(chConfReg & ~MCSPI_CH0CONF_FFER);
// TX FIFO sperren
chConfReg=(chConfReg & ~MCSPI_CH0CONF_FFEW);
// SPI_D0 für Empfang wählen
chConfReg=(chConfReg & ~MCSPI_CH0CONF_IS);
// SPI_D1 für Senden freigeben
chConfReg=(chConfReg & ~MCSPI_CH0CONF_DPE1);
// SPI_D0 für Senden sperren
chConfReg=(chConfReg | (MCSPI_CH0CONF_DPE0_DISABLED<<MCSPI_CH0CONF_DPE0_SHIFT));
// Senden und Empfangen
chConfReg=(chConfReg & ~MCSPI_CH0CONF_TRM);
// 8 Bit pro Transfer aussenden
chConfReg=(chConfReg & ~MCSPI_CH0CONF_WL);
chConfReg=(chConfReg | (MCSPI_CH0CONF_WL_8BITS<<MCSPI_CH0CONF_WL_SHIFT));
// SPIEN ist aktiv low
chConfReg=(chConfReg | (MCSPI_CH0CONF_EPOL_ACTIVELOW<<MCSPI_CH0CONF_EPOL_SHIFT));
// SPICLK=(SPI_CLK/2)=24MHz
chConfReg=(chConfReg & ~MCSPI_CH0CONF_CLKD);
chConfReg=(chConfReg | (MCSPI_CH0CONF_CLKD_DIVBY2<<MCSPI_CH0CONF_CLKD_SHIFT));
// SPICLK ist aktiv high
chConfReg=(chConfReg & ~MCSPI_CH0CONF_POL);
// Sampling bei der steigenden Clock Flanke
chConfReg=(chConfReg & ~MCSPI_CH0CONF_PHA);
// Channel 0 Configuration Register beschreiben
HWREG(SOC_SPI_0_REGS+MCSPI_CHCONF(0))=chConfReg;
// Kanal 1 konfigurieren
// Aktueller Stand des Channel 1 Configuration Register lesen
chConfReg=HWREG(SOC_SPI_0_REGS+MCSPI_CHCONF(1));
// Clock Granularität 2^x
chConfReg=(chConfReg & ~MCSPI_CH1CONF_CLKG);
// RX FIFO sperren
chConfReg=(chConfReg & ~MCSPI_CH1CONF_FFER);
// TX FIFO sperren
chConfReg=(chConfReg & ~MCSPI_CH1CONF_FFEW);
// SPI_D0 für Empfang wählen
chConfReg=(chConfReg & ~MCSPI_CH1CONF_IS);
// SPI_D1 für Senden freigeben
chConfReg=(chConfReg & ~MCSPI_CH1CONF_DPE1);
// SPI_D0 für Senden sperren
chConfReg=(chConfReg | (MCSPI_CH1CONF_DPE0_DISABLED<<MCSPI_CH1CONF_DPE0_SHIFT));
// Nur Transmit (Transmit-only mode)
chConfReg=(chConfReg & ~MCSPI_CH1CONF_TRM);
chConfReg=(chConfReg | (MCSPI_CH1CONF_TRM_TXONLY<<MCSPI_CH1CONF_TRM_SHIFT));
// 24 Bit pro Transfer aussenden
chConfReg=(chConfReg & ~MCSPI_CH1CONF_WL);
chConfReg=(chConfReg | (MCSPI_CH1CONF_WL_24BITS<<MCSPI_CH1CONF_WL_SHIFT));
// SPIEN ist aktiv low
chConfReg=(chConfReg | (MCSPI_CH1CONF_EPOL_ACTIVELOW<<MCSPI_CH1CONF_EPOL_SHIFT));
// SPICLK=(SPI_CLK/2)=24MHz
chConfReg=(chConfReg & ~MCSPI_CH1CONF_CLKD);
chConfReg=(chConfReg | (MCSPI_CH1CONF_CLKD_DIVBY2<<MCSPI_CH1CONF_CLKD_SHIFT));
// SPICLK ist aktiv low
chConfReg=(chConfReg | (MCSPI_CH1CONF_POL_ACTIVELOW<<MCSPI_CH1CONF_POL_SHIFT));
// Sampling bei der fallenden Clock Flanke
chConfReg=(chConfReg & ~MCSPI_CH1CONF_PHA);
// Channel 1 Configuration Register beschreiben
HWREG(SOC_SPI_0_REGS+MCSPI_CHCONF(1))=chConfReg;
// SPI0 Modul konfigurieren
// Aktueller Stand des Module Control Register lesen
modCtrlReg=HWREG(SOC_SPI_0_REGS+MCSPI_MODULCTRL);
// SPIEN Signal freigeben (4Pin Modus)
modCtrlReg=(modCtrlReg & ~MCSPI_MODULCTRL_PIN34);
// SPI0 soll im Master Modus arbeiten
modCtrlReg=(modCtrlReg & ~MCSPI_MODULCTRL_MS);
// Mehrkanal Betrieb
modCtrlReg=(modCtrlReg & ~MCSPI_MODULCTRL_SINGLE);
// Modul Control Register beschreiben
HWREG(SOC_SPI_0_REGS+MCSPI_MODULCTRL)=modCtrlReg;
// Kanal 0 sperren
HWREG(SOC_SPI_0_REGS+MCSPI_CHCTRL(0))=(HWREG(SOC_SPI_0_REGS+MCSPI_CHCTRL(0)) & ~MCSPI_CH0CTRL_EN_ACTIVE);
// Kanal 1 freigeben
HWREG(SOC_SPI_0_REGS+MCSPI_CHCTRL(1))=(HWREG(SOC_SPI_0_REGS+MCSPI_CHCTRL(1)) | MCSPI_CH1CTRL_EN_ACTIVE);
}
Is this a silicon bug or is the initialisation not in the correct order? Any ideas on how to do a workaround?
Thanks and best regards,
Patrick