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.

MCT8316Z: Cannot write to registers via SPI

Part Number: MCT8316Z
Other Parts Discussed in Thread: DRV8316

We have replaced the MCT8316ZT chip on a MCT8316ZTEVM with a MC8316ZR chip.

Reading all registers via SPI works fine, but I cannot get the chip to accept any writes.

I have tried slower bit rates, other values and other variations with same results. I can set various error bits in status bytes by running a motor from the chip, but values in control bytes never change.

Do I have to do something more than setting the REG_LOCK bits to 011b (3h) to make the chip accepts writes?

See signal plot below for sequence of reading first three status registers and then attempts to write followed by read on each control register:

Detail of one word write for timing:

  • Hi Pär,

    Looks like the reads are correct. 
    For the writes, can you ensure the Clock Polarity = 0 and the Clock Phase = 1? 
    Yes, you need to unlock SPI first in the REG_LOCK register by writing 0x03 before setting other SPI settings. 


    Here is more SPI configuration info: https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/937258/faq-spi-configuration-and-use

    I included some example code below that works with DRV8316/MCT8316Z0R:

    void Config_evm_spi(void)
    {
        //Pin Config
        EALLOW;
        // SPI_MOSI
        GPIO_SetupPinOptions(16, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
        // SPI_MISO
        GPIO_SetupPinOptions(17, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
        // SPI_CLK
        GPIO_SetupPinOptions(56, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
        // SPI_CS
        //GPIO_SetupPinOptions(57, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        GPIO_SetupPinMux(16, GPIO_MUX_CPU1, 1);
        GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 1);
        GPIO_SetupPinMux(56, GPIO_MUX_CPU1, 1);
        //GPIO_SetupPinMux(57, GPIO_MUX_CPU1, 1);
        EDIS;
    
        EALLOW;
        ClkCfgRegs.LOSPCP.all = 0;
        EDIS;
    
        // Initialize SPI FIFO registers
        SpiaRegs.SPIFFTX.all=0xE040;
        SpiaRegs.SPIFFRX.all=0x2044;
        SpiaRegs.SPIFFCT.all=0x0;
    
        //SPI Settings
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;     //SPI Reset On
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;    //SCLK Active High
        SpiaRegs.SPICCR.bit.SPICHAR = 0xF;      //16-bit SPI char
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0;  //No overrun interrupt
        SpiaRegs.SPICTL.bit.CLK_PHASE = 0;      //Phase 0
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;   //Master mode
        SpiaRegs.SPICTL.bit.TALK = 1;           //nSCS enabled
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;      //TX/RX Interrupt Disabled
    
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = ((25000000 / 1000000) - 1);              //Set baud rate to 1MHz
        SpiaRegs.SPIPRI.bit.FREE = 1;           //Set so breakpoints don't disturb transmission
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;   //Exit SPI reset
    
    }
    
    Uint16 spi_xmit(Uint16 spiFrame)
    {
        GPIO_WritePin(13,0);
    
        DELAY_US(1);
    
        SpiaRegs.SPITXBUF=spiFrame;
    
        //Wait for RX flag to indicate SPI frame completion
        while(SpiaRegs.SPIFFRX.bit.RXFFST != 1)
        {
        }
    
        GPIO_WritePin(13,1);
    
        return SpiaRegs.SPIRXBUF;
    }
    
    Uint16 spi_read(Uint16 addr)
    {
        Uint16 commandword = 0;
        uint16_t p_addr = addr;
        uint16_t p_data = 0;
    
        uint16_t calc = ((p_addr << 9) & 0x7E00) | (p_data & 0x00FF);
        uint16_t parity = 0;
        while(calc)
        {
           parity ^= (calc & 1);
           calc >>= 1;
        }
    
        commandword = (0x8000 | (addr << 9) | (parity << 8));
        return spi_xmit(commandword);
    }
    
    Uint16 spi_write(Uint16 addr, Uint16 data)
    {
        Uint16 commandword = 0;
        uint16_t p_addr = addr;
        uint16_t p_data = data;
    
        uint16_t calc = ((p_addr << 9) & 0x7E00) | (p_data & 0x00FF);
        uint16_t parity = 0;
        while(calc)
        {
           parity ^= (calc & 1);
           calc >>= 1;
        }
    
        commandword = ((addr << 9) | (parity << 8) | data);
        return spi_xmit(commandword);
    }


    Thanks,
    Aaron


  • Thanks! That piece of example code made me realize I simply inverted the read/write bit. Now it works as expected.