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.

Starterware/AM3359: SPI Driver issue - SPIEN set to low after Master Mode enabled

Part Number: AM3359
Other Parts Discussed in Thread: AM3354

Tool/software: Starterware

Hey guys

I'm trying to enable my AM3359 to talk to Winbond W25Q128FV serial flash through McSPI.
The board is custom, but the flash chip is assembled correctly - it works fine when accessed from U-Boot.

I'm using pdk_am335x_1_0_5 SPI_v1 driver (non-DMA).
When opening the spi handle (SPI_Open), I see the CS line set to 0 after enabling the Master Mode of McSPI controller.

It goes like this:

     /* Reset SPI Peripheral */
    McSPIReset(hwAttrs->baseAddr);    // SPIEN_0 is HIGH

     ...

     if(SPI_MASTER == params->mode)
     {
          /* Enable SPI Master */
         McSPIMasterModeEnable(hwAttrs->baseAddr);         // SPIEN_0 is immideatly set to LOW

     ...

The problem is, it never gets back HIGH after that, looks like McSPI controller does not drive it at all.
I really cant figure out what is happening. According to TRM it should be driven by McSPI,  being asserted (set to low) only during transfers.

Any ideas, why that can happen?

  • Ilia,
    Are you running the example from C:\ti\pdk_am335x_1_0_5\packages\MyExampleProjects\MCSPI_BasicExample_icev2AM335x_armExampleProject ?
    Do you have the same layout as far as the pins that are connected on your customer board, is the same as ICEv2?

    If not, you may have to make pinmux changes to ensure correct operation.

    Lali
  • Thank you for your answer, Lali.

    As an example code, I've used
    C:\ti\pdk_am335x_1_0_5\packages\ti\drv\spi\test\mcspi_serial_flash\src\main_mcspi_dma_serial_flash_read_write.c

    but without enabling dma. I've inspected Board_init() and all the underlying functions, so I do enable clock and pinmux for mcspi pins.
    The code that does that in my case is an adaptaion of

    C:\ti\pdk_am335x_1_0_5\packages\ti\board\src\evmAM335x\evmAM335x.c
    C:\ti\pdk_am335x_1_0_5\packages\ti\starterware\soc\am335x\am335x_prcm.c
    C:\ti\pdk_am335x_1_0_5\packages\ti\board\src\evmAM335x\evmAM335x_pinmux.c

    in part of MCSPI module enabling and pinmuxing. In my case it looks as follows.

    // EnableMcSpiClock is adaptation of enableModule(uint32_t domainOffset, uint32_t clkCtrlReg, .. )
    // for CHIPDB_MOD_ID_MCSPI

    template<typename HwDesc>
    void EnableMcSpiClock()
    {
        HwRegBlock<HwDesc::PrcmRegs> cmRegs;

        cmRegs[HwDesc::ClkCtrlReg].Field(CM_PER_SPI0_CLKCTRL_MODULEMODE).WriteThrough(CM_PER_SPI0_CLKCTRL_MODULEMODE_ENABLE);

    // Field(bit).WriteThrough just writes specific bit (and only that bit)
    // into the register and waits till it is set to the right value
    // and HwRegBlock<base> cmRegs; cmRegs[reg] - is simply an access
    // to target register, which is base + reg

        cmRegs[HwDesc::ClkStReg].Field(HwDesc::ClkActivityBit).WaitUntilSet();

        cmRegs[HwDesc::ClkCtrlReg].Field(CM_PER_SPI0_CLKCTRL_IDLEST).WaitUntilEquals(CM_PER_SPI0_CLKCTRL_IDLEST_FUNC << CM_PER_SPI0_CLKCTRL_IDLEST_SHIFT);
    }

    struct McSpi0HwDesc
    {
        static constexpr int ModuleIndex = 0;
        static constexpr uint32_t Regs = SOC_SPI_0_REGS;
        static constexpr uint32_t Int = SOC_INT_SPI0INT;

        static constexpr uint32_t PrcmRegs = SOC_CM_PER_REGS;
        static constexpr uint32_t ClkCtrlReg = CM_PER_SPI0_CLKCTRL;
        static constexpr uint32_t ClkStReg = CM_PER_L3_CLKSTCTRL;
        static constexpr uint32_t ClkActivityBit = CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK;
    };

    template class McSpi<McSpi0HwDesc>;

    ...


    Then PinMuxing. The code for SPI pins is

    ...
    SetMux(CONTROL_CONF_SPI0_SCLK,    Fast | IEn | PU | Mode0);
    SetMux(CONTROL_CONF_SPI0_D0,         Fast | IEn | PU | Mode0);
    SetMux(CONTROL_CONF_SPI0_D1,         Fast | IEn | PU | Mode0);
    SetMux(CONTROL_CONF_SPI0_CS0,      Fast | IEn | PU | Mode0);
    ...

    void SetMux(uint32_t pin, uint32_t val)
    {
         HwRegBlock<SOC_CONTROL_REGS>()[pin] = val;
    }

    // Fast = 0,
    // IEn = CONTROL_CONF_RXACTIVE
    // PU = CONTROL_CONF_PULLUPSEL
    // Mode0 = CONTROL_CONF_MUXMODE(0)


    Hope that helps to clarify things a bit..

    Thank you!

  • Hi Ilia,

    You can check to see if the Pin mux is set as you anticipate by looking at pinmux register in memory

    The Pin mux is in the control module the base address is shown in the memory map section of theTRM http://www.ti.com/lit/pdf/spruh73  to be at 0x44E1_0000

    The locations for the pins a in the TRM Table 9-10

    Offset Pin name Register Description Section

    950h      conf_spi0_sclk      Section 9.3.1.50

    954h      conf_spi0_d0       Section 9.3.1.50

    958h      conf_spi0_d1      Section 9.3.1.50

    95Ch     conf_spi0_cs0     Section 9.3.1.50

    960h     conf_spi0_cs1      Section 9.3.1.50

     

    The pad control registers are shown 9-1


  • I've checked the registers, they seem to look fine, don't they?

    conf_spi0_sclk 0x00000030   

    conf_spi0_d0 0x00000030

    conf_spi0_d1 0x00000030

    conf_spi0_cs0 0x00000030

    conf_spi0_cs1 0x00000030

    0x00000030 is fast (0), rxactive(1), pulltypesel - pullup(1), pullup/pulldown enabled (0), muxmode (0)

  • Hi Ilia,
    To drive an output the RX should be disabled for that pin.

    David
  • Thank you, David.

    I've changed pinmux to this

    conf_spi0_sclk 0x00000030
    conf_spi0_d0 0x00000030
    conf_spi0_d1 0x00000030
    conf_spi0_cs0 0x00000010
    conf_spi0_cs1 0x00000010

    0x00000030 is fast (0), rxactive(0), pulltypesel - pullup(1), pullup/pulldown enabled (0), muxmode (0)

    but, unfortunately, the rest stays the same.

    CS0 goes low right after SPI_Open (McSPIMasterModeEnable)

  • Hi Ilia,

    I apologize I should have noticed this earlier.

    The MCSPI_SerialFlash example (  http://processors.wiki.ti.com/index.php/Processor_SDK_RTOS_QSPI-McSPI ) is developed for the AM335 General Purpose EVM http://www.ti.com/tool/tmdxevm3358 . This EVM uses only SPI0_CLK and SPI0_D0  for communication to and the SPIFlash which is a W25Q64 that is on the daughercard. The Pinmux setting for each of these signals are 0x20.  These signals are not directly connected to the Flash. Instead they pass though a CPLD which provides inputs for SPI_Clk, SPI_DI, SPI_DO, and SPI_CS on the flash. The pin mux setting for SPI0_D1 and SPI0_CS0 are to configure them for I2C operation.

    There is a starterware SPI flash read/write utility for the AM335 ICE V2  EVM http://www.ti.com/tool/tmdsice3359 . . 

    This EVM has following direct connections to the AM3359.  The Pinmux settings for this are

    conf_spi0_sclk  0x00000028 
    conf_spi0_d0   0x00000028 
    conf_spi0_d1   0x00000000 
    conf_spi0_cs0  0x00000000 

    The application is starterware mcspi_app_flash. When Building it is necessary to also have the starterware board, dal, device, example_utils, soc, and utils in the environment.

    I have no problem building this application under the Industrial SDK http://www.ti.com/tool/sysbiossdk-ind-sitara with CCS 6.2.1 and GNU v4.8.4 .

    I will need to do some investigation on how to build this under pdk_am335x_1_0_5

    David

    .

  • Hi David,

    I've used the code as an example only.

    I have a custom board, though with a very simple SPI flash assembly:

    So, as soon as I disable MasterMode on mcspi, cs0 goes back UP.

    I thought maybe something is wrong with the specific chip I use, but I see the same thing on another (AM3354) chip that I've just checked.