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.

DM365 MDSTAT Register

I have been trying to get the SPI port to work on a DM365 board.

After some debugging, I read the MDSTAT register for the SPI port I am trying to use and it read 0xf020000.

This seems to indicate that the peripheral is powered down. Writing 0x3 to the MDCTL resister does change the MDSTAT register to 0xe020000, but I still can't get any data out, and the module state status is still set to SwResetDisable. 

Asserting and De-asserting the local reset seems to have no effect.

What do I need to do to change the module state? What do the upper bits indicate that are being changed (they are listed reserved in the documentation)?

Thanks for your input,

   Dan

  • Support,

    I am using the SDK 3.10.  Note the comment on the section setting up the PSC controller. The PSC state change never occurs, and if we poll for the change (as the TI code sample in the evmdm365_psc.c does), it hangs.
    Is this the correct sequence?
     ======================================================
    The code to set up the PSC controller:
     
            tmpValue = SPI_REG(DM365_PTSTAT);
            while (tmpValue & 0x1)
                    tmpValue = SPI_REG(DM365_PTSTAT);
     
            tmpValue = SPI_REG(DM365_SPI0_MDCTRL) & ~0x1f;
            SPI_REG(DM365_SPI0_MDCTRL) = tmpValue | 0x3;
     
            SPI_REG(DM365_PTCMD) = 0x1;
     
            tmpValue = SPI_REG(DM365_PTSTAT);
            while (tmpValue & 0x1)
                    tmpValue = SPI_REG(DM365_PTSTAT);
     
            // This will hang; the state never changes...
            //tmpValue = SPI_REG(DM365_SPI0_MDSTAT);
            //while ( (tmpValue & 0x1f) != 0x3 )
            //      tmpValue = SPI_REG(DM365_SPI0_MDSTAT);
     
    The SPI_REG macro:
     
    #define SPI_REG(reg)    (*(int *__iomem) IO_ADDRESS(reg))
    =====================================
     
    The function to set up the spi0 port:
     
    int dm365_spi0_config(void)
    {
     unsigned int tmpValue;
     
     // Power up the SPI hardware by requesting and enabling the clock
     g_clkptr = clk_get(NULL, "SPICLK");
     
     if(g_clkptr <= 0)
     {
      printk("<l>Error could not get the clock\n");
      return -ENOTTY;
     }
     else clk_enable(g_clkptr);
     
     // Configure Pins for SPI (and not GPIO)
     tmpValue = SPI_REG(DM365_PINMUX3);
     tmpValue = tmpValue & ~(76 << 24);
     tmpValue = tmpValue | (36 << 24);
     SPI_REG(DM365_PINMUX3) = tmpValue;
     
     // Reset SPI
     SPI_REG(DM365_SPI0_SPIGCR0) = 0x00000000;
     mdelay(1);
     // Remove from reset
     SPI_REG(DM365_SPI0_SPIGCR0) = 0x00000001;
     


     // Enable SPI CLK & Master
     SPI_REG(DM365_SPI0_SPIGCR1) = 0x00000003;
     
     // Enable SPI pins as 'functional pins'
     SPI_REG(DM365_SPI0_SPIPC0) = 0x00000E03;
     
     /* --------------------------------
     // Set data format in SPIFMT0 - THIS CAN BE CHANGED BY IOCTL commands
     // SHIFTDIR in bit 20 set to 1 : MSB first
     // POLARITY and PHASE in bit 17, 16 set to 0, 0
     // PRESCALE in bit 15-8 set to whatever you need, SPI_CLK = SYSCLK5 / (Prescale + 1)
     // CHARLEN in bit 4-0 set to 08 : 8 bit characters
     -------------------------------- */
     tmpValue=0x00000000 | (SPI_POLARITY << 17) | (SPI_PHASE << 16) | (0x7 << 8) | 0x8;
     SPI_REG(DM365_SPI0_SPIFMT0) = tmpValue;
     
     // Set data format for used -> SPIFMT0
     tmpValue = 0x00000000 & (0x00 << 24);
     SPI_REG(DM365_SPI0_SPIDAT1) = tmpValue;
     
     // Set hold time and setup time
     tmpValue = 0x00000000 | (0x03 << 16) | (0x06 << 24);
     SPI_REG(DM365_SPI0_SPIDELAY) = tmpValue;
     
     // --------------------------------
     // Set Chip Select Default
     // CSHOLD -> 0 -> release SPI_EN0 state after transmission-> bit 28
     // CSNR -> 2 -> Only use SPI_EN0
     // --------------------------------
     tmpValue = SPI_REG(DM365_SPI0_SPIDAT1);
     tmpValue = tmpValue & (0xc << 16);
     tmpValue = tmpValue | (0x2 << 16);
     SPI_REG(DM365_SPI0_SPIDAT1) = tmpValue;
     
     // Enable for transmitting
     tmpValue = SPI_REG(DM365_SPI0_SPIGCR1);
     tmpValue = tmpValue | (1 << 24);    // enable SPIENA
     SPI_REG(DM365_SPI0_SPIGCR1) = tmpValue;
     
     // Zero out our read buffer
     memset(g_readbuf, 0, 1024);
     g_readbufcount = 0;
     return 0;
    }

     
    The code to set up the PSC controller:
     
            tmpValue = SPI_REG(DM365_PTSTAT);
            while (tmpValue & 0x1)
                    tmpValue = SPI_REG(DM365_PTSTAT);
     
            tmpValue = SPI_REG(DM365_SPI0_MDCTRL) & ~0x1f;
            SPI_REG(DM365_SPI0_MDCTRL) = tmpValue | 0x3;
     
            SPI_REG(DM365_PTCMD) = 0x1;
     
            tmpValue = SPI_REG(DM365_PTSTAT);
            while (tmpValue & 0x1)
                    tmpValue = SPI_REG(DM365_PTSTAT);
     
            // This will hang; the state never changes...
            //tmpValue = SPI_REG(DM365_SPI0_MDSTAT);
            //while ( (tmpValue & 0x1f) != 0x3 )
            //      tmpValue = SPI_REG(DM365_SPI0_MDSTAT);
     
    The SPI_REG macro:
     
    #define SPI_REG(reg)    (*(int *__iomem) IO_ADDRESS(reg))
     
  • Hi Marc,

    The above code does not look like PSP 3.x code. In PSP 3.x, the code to enable/disable PSC is here: http://arago-project.org/git/projects/?p=linux-davinci.git;a=blob;f=arch/arm/mach-davinci/psc.c;h=a78b657e916e9c44425e8c913e6160bc833089bc;hb=3df7eda25fe6477a6005556fce821dbe86475c8d#l63

    This is called through clk_enable() API call from probe function of SPI driver here: http://arago-project.org/git/projects/?p=linux-davinci.git;a=blob;f=drivers/spi/davinci_spi.c;h=956f6170433ff7e0b0b3a49a8d474849baaa15f6;hb=3df7eda25fe6477a6005556fce821dbe86475c8d#l985

    In the code snippets posted above, there seems to be a lot of custom code written which should not really be needed.

    Thanks,

    Sekhar

  • Thanks for the feedback, we have been able to get the above code to work by adding memory barriers between some of the writes.

    In parallel, we are mograting over to the latest DVSDK.

    Thanks for the feedback!