This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x McSPI glitch on SPIEN

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