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