MP6602 No Power to Motor while No Fault Condition

I had some issues with the code on the Pic Processor and I would like to post that information for the sake of someone else who might want more background on a design close to this one.
Here is the link: https://forum.microchip.com/s/topic/a5CV40000002DZ3MAM/t398142

The software I used was used to operate another and simpler motor, but not a stepper. I added the Stepper Motor Code to it, most of it with MP6022 names for the routines. I include the main.c file here simply so you can see what I am attempting or how I am testing the MP6022. The important part is setup and operation of the MP6022. I did not write this code for you to look at, so ask me if you have questions about what part I think it doing what with; it is probably difficult to follow without some study. I think writing a “1” to the Ctrl.step bit should make the motor advance.

At the first occurrence of “for(int i = 0; i < 200; i++) {” is where I have the motor setup as in the application node and am sending STEP commands - expecting the motor to operate.

Here is main.c

/*

  • File: main.c
  • Author: tmiller

*/

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include “user.h”
#include “system.h”
#include “MP6602.h”

volatile unsigned int pulseCount;
volatile unsigned int Timer0Int;

char lastStep;

unsigned int nFault = 0;

extern unsigned int SPIRead, ReadSDI;

unsigned int MP6602RegisterValues[8];

int main(int argc, char** argv) {

static unsigned char Answer1, Answer2;

unsigned long int i;
int avgIntPerRev;           // Calibrated value of interrupts in Capacitance range.
int totalintLimit;
double tuning;
double oldtuning;
int numberOfSteps;
int oldNumberOfSteps;
unsigned char direction;
unsigned int oldPulseCount;
unsigned int stepCount;
unsigned int savPulseCount;
unsigned int firstPulseCount = 0;
char buf[10], sbuf[5];

unsigned int OffTimeChanged = 0;
unsigned int StepModeChanged = 0;
unsigned int EnableChanged = 0;
unsigned int BlankingTimeChanged = 0;
unsigned int SteppingCurrentLimitChanged = 0;
unsigned int StepIndexChanged = 0;
unsigned int Faultschanged = 0;
unsigned int STEPChanged = 0;

PMD0bits.NVMMD = 1;  // Disable NVM Module
PMD1bits.NCOMD = 1; // Disable NCO
PMD1bits.TMR6MD = 1;  // Disable TMR6
PMD1bits.TMR5MD = 1;  // Disable TMR5
PMD1bits.TMR4MD = 1;  // Disable TMR4
PMD1bits.TMR3MD = 1;   // Disable TMR3
PMD2bits.DACMD = 1;     // Disable DAC
PMD3bits.CWG1MD = 1;    // Disable CWG
PMD3bits.CWG2MD = 1;    // Disable CWG
PMD3bits.PWM6MD = 1;    // Disable PWM
PMD3bits.CCP4MD = 1;    // Disable Capture and Compare
PMD3bits.CCP3MD = 1;
PMD3bits.CCP2MD = 1;
PMD3bits.CCP1MD = 1;
PMD4bits.UART1MD = 1;   // Disable UART1
PMD4bits.MSSP2MD = 1;   // Disable MSSP
PMD5bits.CLC1MD = 1;    // Disable Configure Logic Cell
PMD5bits.CLC2MD = 1;    // Disable CLC2
PMD5bits.CLC3MD = 1;    // Disable CLC3
PMD5bits.CLC4MD = 1;    // Disable CLC4
PMD5bits.DSMMD = 1;     // Disable DSM


// MP6602 FAULT Pin Configuration
// The nFAULT pin reports fault conditions and
// is driven low when a fault condition occurs.
// If the fault condition is released, the nFAULT
// pin is pulled high by an external pull up resistor.
// So long as the pin is high there is no fault condition 1=NoFault
// It reflects the bit setting in the FAULT register
LATCbits.LATC5 = 0;         // Clear the Latch of the FAULT pin
ANSELCbits.ANSC5 = 0;       // Digital port
ODCONCbits.ODCC5 = 1;       // Open Drain (Sink Current Only) Disabled
TRISCbits.TRISC5  = 1;      // Fault pin of MP6022
WPUCbits.WPUC5 = 1;         // The MP6602 nFault Pin is pulled high by this resistor 



// Port Control

// 18345 Output LED
ANSELAbits.ANSA5 = 0;   // Digital pin
INLVLAbits.INLVLA5 = 0; // TTL Input Level for Input / Its an Output Pin
LATAbits.LATA5 = 0;     // Nothing out yet
ODCONAbits.ODCA5 = 0;   // Open Drain on (Sink Current Only) OFF/ its output
SLRCONAbits.SLRA5 = 1;  // Slew Rate Control on - to make it easier on the processor
TRISAbits.TRISA5 = 0;   // Port is Output
WPUAbits.WPUA5 = 0;     // Weak Pull Up Resistor not used.
LATAbits.LATA5 = 1;


// Enable Pin MP6602
ANSELCbits.ANSC1= 0;    // Digital Pin
INLVLCbits.INLVLC1 =0;  //TTL Input -its an output
ODCONCbits.ODCC1 = 1;   // Not Open Drain (Sinks and Sources current)
SLRCONCbits.SLRC1 = 1;  // Slew Rate Control On
TRISCbits.TRISC1 = 0;   // Output to enable/disable (Pin,not register)
WPUCbits.WPUC1 = 0;     // No pull up (i is internal pull down)
LATCbits.LATC1 = 0;     // MP6602 Not Enabled through this pin

// Step Pin MP6602
ANSELCbits.ANSC2 = 0;    // Digital Pin
INLVLCbits.INLVLC2 =0;  //TTL Input -its an output
ODCONCbits.ODCC2 = 1;   // Not Open Drain (Sinks and Sources current)
SLRCONCbits.SLRC2 = 1;  // Slew Rate Control On
TRISCbits.TRISC2 = 0;   // Output to STEP (Pin,not register)
WPUCbits.WPUC2 = 0;     // No pull up (i is internal pull down)
LATCbits.LATC2 = 0;     // MP6602 Not Enabled through this pin    

// DIR (direction) Pin MP6602
ANSELCbits.ANSC4= 0;    // Digital Pin
INLVLCbits.INLVLC4 =0;  //TTL Input -its an output
ODCONCbits.ODCC4 = 1;   // Not Open Drain (Sinks and Sources current)
SLRCONCbits.SLRC4 = 1;  // Slew Rate Control On
TRISCbits.TRISC4 = 0;   // Output to DIR (Pin,not register)
WPUCbits.WPUC4 = 0;     // No pull up (i is internal pull down)
LATCbits.LATC4 = 0;     // MP6602 Not Enabled through this pin    


        



INTCONbits.GIE = 1;     // Enable all interrupts that are enabled.
INTCONbits.PEIE = 1;
CLKRCONbits.CLKREN = 0;     // Reference clock disabled.

#ifdef USE_IOC

PIE1 = 1;    // Enable timer 2 interrupt
INTCONbits.GIE = 1;     // Enable all interrupts that are enabled.
INTCONbits.INTE = 0;

// Stepper Motor Setup

RB6PPS = 0b11000;   // RC6 port at pin 11 is assigned as SCK1
SSP1CLKPPS = 0b01110;   // SCLK1 is at RB6
RB5PPS = 0b11001;    // RB5 port at pin 12 is assigned as SDO1
SSP1DATPPS = 0b1100;   // Peripheral SSP1SDI is at RB4
SSP1SSPPS = 0b10110;    // SS1 is at RC6 pin 8

LATBbits.LATB4 = LATBbits.LATB5 = LATBbits.LATB6 = LATCbits.LATC6 = 0;
ANSELBbits.ANSB4 = ANSELBbits.ANSB5 = ANSELBbits.ANSB6 = ANSELCbits.ANSC6 = 0;  // Digital pins
WPUBbits.WPUB4 = WPUBbits.WPUB5 = WPUBbits.WPUB6 = WPUCbits.WPUC6 = 1;     // Weak Pull ups
ODCONBbits.ODCB4 = 1;   // Open drain (sink current only)
SLRCONBbits.SLRB4 = 1;  // Slew Rate enabled (slows it down)
INLVLBbits.INLVLB4 = 1; // ST input (lower voltage for high)
TRISBbits.TRISB4 = 1;   // SDI (TRIS=1) RB4/13
TRISBbits.TRISB5 = 0;   // SDO (TRIS=0) RB5/12
TRISBbits.TRISB6 = 0;   // SCLK (TRIS=0) RB6/11
TRISCbits.TRISC6 = 0;   // ~SS (TRIS=1) RC6/8

// SP1BRG = 0x13; // 400kHz
// SPI Interrupts
PIR1bits.SSP1IF = 0; // Clear Read/Write Status interrupt Flag
PIR1bits.BCL1IF = 0; // Clear Bit Collision on SPI1 interrupt Flag
PIE1bits.SSP1IE = 1; // Read or write complete on SPI1
PIE1bits.BCL1IE = 1; // Bit Collision on SPI1

// PMD4bits.MSSP1MD = 0; // Enable MSSP module to set ports

SSP1ADD = 0x13;     // 400kHz    
SSP1CON1bits.SSPM = 0b1010;      // SPI Master Mode, clock = FOSC/4 = 32MHz/64 = 500kHz
SSP1CON1bits.CKP = 1;  // Clock idle (Clock Polarity) state is high so MP6620 Data shifts on the rising edge of SCLK
SSP1STATbits.CKE = 0;  // Transmit occurs on transition from active to idle clock state.
SSP1STATbits.SMP = 0;   // Input data sampled at end of data output time.


SSP1CON1bits.SSPEN = 1;  // ENable SPI

LATCbits.LATC7 = 0;
LATCbits.LATC1 = 0;
LATBbits.LATB7 = 0;
LATCbits.LATC2 = 0;
LATCbits.LATC4 = 0;
ANSELCbits.ANSC7 = 0;       // Reset Pin digital
ANSELCbits.ANSC1 = 0;       // Enable Pin digital
ANSELBbits.ANSB7 = 0;       // Sleep Pin digital 
ANSELCbits.ANSC2 = 0;       // STEP Pin digital
ANSELCbits.ANSC4 = 0;       // DIR Pin digital
TRISCbits.TRISC7 = 0;       // Reset Pin output
TRISCbits.TRISC1 = 0;       // Enable Pin output
TRISBbits.TRISB7 = 0;       // Sleep Pin Output
TRISCbits.TRISC2 = 0;       // STEP pin Output
TRISCbits.TRISC4 = 0;       // DIR Pin Output

// Leave enable pin dis-enabled (C1)   
// Leave out of sleep (B7)
// Leave STEP not stepping (C2)
// Leave DIR the same (low/C4)

// Reset MP6602 - drive pin 7 reset  low           
WPUCbits.WPUC7 = 1;     // Enable weak pull up on Reset Pin
LATCbits.LATC7 = 1;     // Pull up Reset to end RESET (C7)
LATBbits.LATB7 = 0;     // Sleep mode inactive
LATCbits.LATC1 = 0;     // Enable through register, not pin
__delay_ms(1);  


static unsigned int CtrlValue;
static unsigned int RegisterValue;

//
// First one does not work well.
CtrlValue = ReadMP6602(0x00);

FAULTRegValue = ReadMP6602(0x0E);       // Read the Fault register because VCCUV is holding the device in RESET mode
FillFAULTRegStruct(FAULTRegValue);      // Fill in the structure
FAULTReg.VCCUV = 1;                     // Write a 1 to VCCUV to clear Reset mode
FAULTRegValue = MakeFAULTRegDataInteger();  // Make the integer to write to the FAULT register
WriteMP6602(0x0E,FAULTRegValue);        // Write to the FAULT Register
FAULTRegValue = ReadMP6602(0x0E);       // Read it back to verify

// Read All The Initial Register Values
CtrlRegValue = MP6602RegisterValues[0] = ReadMP6602(0x00);    
Ctrl2RegValue = MP6602RegisterValues[1] = ReadMP6602(0x02);
ISETRegValue = MP6602RegisterValues[2] = ReadMP6602(0x04);
StallRegValue = MP6602RegisterValues[3] = ReadMP6602(0x06);
BEMFRegValue = MP6602RegisterValues[4] = ReadMP6602(0x08);
TSTPRegValue = MP6602RegisterValues[5] = ReadMP6602(0x0A);
OCPRegValue = MP6602RegisterValues[6] = ReadMP6602(0x0C);
FAULTRegValue = MP6602RegisterValues[7] = ReadMP6602(0x0E);



// Read Control Register 1 and fill in the CtrlReg Structure
// It includes the hold time, the off time, the step mode/increment,
// the direction, step, and enable commands.

ISETRegValue = ReadMP6602(0x04); // Read the ISET Register
FillISETRegStruct(ISETRegValue); // Fill in the stored Structure copy
ISETReg.PeakCurrentStepping.IS = 0x0b; // Set Step Current at 1.5 Amperes
ISETRegValue = MakeISETRegDataInteger(); // Make the new Data Value word.
WriteMP6602(0x04,ISETRegValue); // Configure the MP6602
ISETRegValue = ReadMP6602(0x04); // Read the ISET Register to confirm

CtrlRegValue = ReadMP6602(0x00); // Read Ctrl Register to change off time
FillCtrlRegStruct(CtrlRegValue); // Fill in processor memory copy
CtrlReg.OffTime.OT = 0b111; // Modify (fixed) Off Time (between steps)
CtrlRegValue = MakeCtrlRegDataInteger(); // Make the register transmit value
WriteMP6602(0x00,CtrlRegValue); // Write to the Motor Controller (MP6602)
CtrlRegValue = ReadMP6602(0x00); // Read back Ctrl to confirm

Ctrl2RegValue = ReadMP6602(0x02); // Read Ctrl2 Register to change blanking time
FillCtrlRegStruct(Ctrl2RegValue);
Ctrl2Reg.BlankingTime.BT = 0b111;
Ctrl2RegValue = MakeCtrl2RegDataInteger();
WriteMP6602(0x02,Ctrl2RegValue);
Ctrl2RegValue = ReadMP6602(0x02); // Read Back Ctrl2 to verify

CtrlRegValue = ReadMP6602(0x00); // Read Ctrl Register to change Step Mode
FillCtrlRegStruct(CtrlRegValue);
CtrlReg.StepModeTime.MS = 0b101;
CtrlRegValue = MakeCtrlRegDataInteger();
WriteMP6602(0x00,CtrlRegValue);
CtrlRegValue = ReadMP6602(0x00); // Read Ctrl Register to verify

TSTPRegValue = ReadMP6602(0x0A); // Read TSTP Register to start step counter at 0
FillCtrlRegStruct(TSTPRegValue);
TSTPReg.StepIndex.STP = 0;
TSTPRegValue = MakeTSTPRegDataInteger();
WriteMP6602(0x0A,TSTPRegValue);
TSTPRegValue = ReadMP6602(0x0A); // Read TSTP Register to verify

CtrlRegValue = ReadMP6602(0x00); // Read Ctrl Register to set enable bit
FillCtrlRegStruct(CtrlRegValue);
CtrlReg.EN = 1;
CtrlRegValue = MakeCtrlRegDataInteger();
WriteMP6602(0x00,CtrlRegValue);

CtrlRegValue = ReadMP6602(0x00); // Read Ctrl Register to set enable bit
FillCtrlRegStruct(CtrlRegValue);
CtrlReg.STEP = 1;
CtrlRegValue = MakeCtrlRegDataInteger();

unsigned int changed = checkRegisterValues(CtrlRegValue,Ctrl2RegValue,ISETRegValue,StallRegValue,BEMFRegValue,TSTPRegValue,OCPRegValue,FAULTRegValue);
if(changed & 0b10000000)
if (!((CtrlRegValue&0b000000000010) & 0b000000000010))
NOP(); // Step Changed
if(changed & 0b00010000)
NOP(); // Stall changed
if(changed & 0b00001000)
NOP(); // BEMF changed

for(int i = 0; i < 200; i++) {
WriteMP6602(0x00,CtrlRegValue);
CtrlRegValue = ReadMP6602(0x00); // Read Ctrl Register to set enable bit
FillCtrlRegStruct(CtrlRegValue);
TSTPRegValue = ReadMP6602(0x0A);
CtrlReg.STEP = 1;
CtrlRegValue = MakeCtrlRegDataInteger();
TSTPRegValue = ReadMP6602(0x0A); // Read TSTP Register to start step counter at 0
FillCtrlRegStruct(TSTPRegValue);
__delay_ms(1000);
}

   TSTPRegValue = ReadMP6602(0x0A);
   FillTSTPRegStruct(TSTPRegValue);   

for (int i = 0; i< 200; i++) {

   TSTPReg.StepIndex.STP = 0;
   TSTPRegValue = MakeCtrlRegDataInteger();
   WriteMP6602(0x0A,TSTPRegValue);
   TSTPReg.StepIndex.STP = 0x20;
   TSTPRegValue = MakeCtrlRegDataInteger();       
   WriteMP6602(0x0A,TSTPRegValue);

}

changed = checkRegisterValues(CtrlRegValue,Ctrl2RegValue,ISETRegValue,StallRegValue,BEMFRegValue,TSTPRegValue,OCPRegValue,FAULTRegValue);
if(changed & 0b10000000)
if (!((CtrlRegValue&0b000000000010) & 0b000000000010))
NOP(); // Step Changed
if(changed & 0b00010000)
NOP(); // Stall changed
if(changed & 0b00001000)
NOP(); // BEMF changed

for(int i = 0; i < 10; i++) {
PORTCbits.RC2 = 1; // Step
}

// Change the stored copy

// while(1) {
// Alter the memory copy of the first Control register to step
// CtrlReg.STEP = 1;
// Make the data integer to write to the MP6602
// CtrlRegValue = MakeCtrlRegDataInteger(); // Fill in the bitwise Ctrl Register Value
// Write the new contents with the step bit set (should step the motor)
// CtrlValue = WriteMP6602(0x00,CtrlRegValue); // Write the new value
// Read ALL the Registers and fill in the associcated structures.

while(!(OffTimeChanged || StepModeChanged || EnableChanged ||
BlankingTimeChanged || SteppingCurrentLimitChanged ||
StepIndexChanged || Faultschanged)) {
CtrlRegValue = ReadMP6602(0x00);
FillCtrlRegStruct(CtrlRegValue);
if(CtrlReg.OffTime.OT != 0b111)
OffTimeChanged = 1;
if(CtrlReg.StepModeTime.MS != 5)
StepModeChanged = 1;
if(CtrlReg.EN != 1)
EnableChanged = 1;

    Ctrl2RegValue = ReadMP6602(0x02);
    FillCtrl2RegStruct(Ctrl2RegValue);       
    if(Ctrl2Reg.BlankingTime.BT != 0b111)
        BlankingTimeChanged = 1;

    ISETRegValue = ReadMP6602(0x04);
    FillISETRegStruct(ISETRegValue);
    if(ISETReg.PeakCurrentStepping.IS != 0x0B)
        SteppingCurrentLimitChanged = 1;
    
    StallRegValue = ReadMP6602(0x06);
    FillStallRegStruct(StallRegValue);
    
    BEMFRegValue = ReadMP6602(0x08);
    FillBEMFRegStruct(BEMFRegValue);
    
    TSTPRegValue = ReadMP6602(0x0A);
    FillTSTPRegStruct(TSTPRegValue);
    if(TSTPReg.StepIndex.STP != 0)
        StepIndexChanged = 1;
    
    OCPRegValue = ReadMP6602(0x0C);
    FillOCPRegStruct(OCPRegValue);
    
    FAULTRegValue = ReadMP6602(0x0E);
    FillFAULTRegStruct(FAULTRegValue);
    if(FAULTRegValue != 0)
        Faultschanged = 1;
    
    __delay_ms(2000);
   };

// // Record the change to the 1st Control Structure (so I can see what changed)
// FillCtrlRegStruct(CtrlRegValue);
// // Read the Step Table register to see if it increments
// TSTPRegValue = ReadMP6602(0x0A); // Read the Step Register
// // Record the state of the step table to the memory structure
// FillTSTPRegStruct(TSTPRegValue); // fill in the most recent data.
// }

CtrlRegValue = ReadMP6602(0x00);    // Read the new value from the MP6602

CtrlRegValue = MakeCtrlRegDataInteger();
while(1) {

// CtrlValue = WriteMP6602(0x0,CtrlValue);
NOP();

// CtrlRegValue = ReadMP6602(0x00);
}
CtrlValue = WriteMP6602(0x0,CtrlRegValue);
CtrlRegValue = ReadMP6602(0x00);
CtrlValue = WriteMP6602(0x0,CtrlRegValue);
CtrlRegValue = ReadMP6602(0x00);
CtrlValue = WriteMP6602(0x0,CtrlRegValue);
// ISETReg.ISETRegValue = ReadMP6022(0x40);
// StallReg.StallRegValue = ReadMP6022(0x60);
// BEMFReg.BEMFRegValue = ReadMP6022(0x80);
// TSTPReg.TSTPRegValue = ReadMP6022(0xA0);
// OCPReg.OCPRegValue = ReadMP6022(0xC0);
// FAULTReg.FAULTRegValue = ReadMP6022(0xE0);

SPIRead = 0;  // Do not read on interrupt
LATCbits.LATC6 = 1;  // Slave not selected 


RegisterValue = ReadMP6602(0x0);
RegisterValue = RegisterValue ^ 0x038;      // Exclusive or will zero all these bits out
RegisterValue = RegisterValue | 0x028;      // Set the step size in 3 bits (1/32)
RegisterValue = WriteMP6602(0x0, RegisterValue);    // 1/32 step size
RegisterValue = WriteMP6602(0x0,0x100);    // Off Time (default 40us)
RegisterValue = WriteMP6602(0x2,0x004);     // Blanking time (default 2us)
RegisterValue = WriteMP6602(0x4,0x280);     //  Hold Mode steeping 1.5A
RegisterValue = WriteMP6602(0x0,0x200);     // Time until Automatic Hold Time stops (15.6ms)