I'm trying to control an Adafruit stepper motor with the high-end timer (NHET) module of a Texas Instruments Hercules microcontroller I got a freebie from TI almost a year ago. An Adafruit stepper motor, a driver board and a Hercules RM57 LaunchPad. The code to run the motor was expected to arrive too (it was an assignment for an internal) but that never materialised. In this blog series I'm trying to program the NHET module so that it sends the right signals to make the stepper step.
In the 8th blog I finally try to create the dynamic pulses for the Stepper Motor with the Hercules HET module. |
When you think something is complex, and it's already been done and published
N2HET Based Pulse Train Output
(first it was called HET, then NHET for New HET, now N2HET for New Advanced 2nd Ggeneration HET. Don't ask me. Call TI)
I have found an application note for the Hercules RM57: "TI Designs: High Availability Industrial High Speed Counter (HSC) / Pulse Train Output (PTO)".
An amazing document that shows how to control production line belt using counters and pulses to check and drive it.
I am interested in the part that explains how to program the HET module to drive a stepper motor.
The appnote supports three ways to drive the motor.
I'm using the document's count/dir functionality to generate period-shifted pulses, because the DRV8711 stepper motor controller expects pulses.
Ramp up and Ramp down Profiles
The HET design supports stable speed, ramp-up and ramp-down. All functions accept the number of pulses to generate.
In the stable speed function, the requested number of pulses are generated with the same time base.
In the two ramp-xx functions, the period of the pulses decreases (ramp-up) or increases (ramp-down) linear.
The HET is programmed as an autonomous state machine.
The only duty for the ARM core (called HOST DRIVER on the above state diagram) of the Hercules controller is to fill the command buffer with a profile:
ptoInit(pto1, ptoModeCountDir); ptoCmdCreate(&cmdList[0], 1000000, 50, ptoDirRev, ptoAccLinAcc); ptoCmdCreate&cmdList[1 105132 10 ptoDirRev ptoAccZero ptoCmdCreate&cmdList[2 105132 50 ptoDirRev ptoAccLinDec // ... ptoStart(pto1); for (i = 0; i < NUMCMD; i++) { ptoCmdSubmit(pto1, cmdList[i]); }
* ptoRetVal_t ptoCmdCreate(ptoCmd_t *cmd, uint32_t icnt, uint32_t nstp, ptoDir_t dir, ptoAcc_t acc); * - icnt = initial pulse width (in counts of N2HET High Resolution Clocks * - nstp = number of steps to execute in the command * - dir = direction of steps (forward, reverse, or pure time delay) * - acc = acceleration type (accelerate, decelerate, or zero acceleration/constant speed) */
HET will first pulse out a train of 50 pulses, with the pulse width 1 000 000 times the period of NHET clock as start period:
If I count correctly, 1 / 110 MHz * 1 000 000 = 9.090909.... ms. Let's check on a capture of the sequence above with the logic analyzer:
Spot on!.
Then 10 steps at the stable speed of 1 110 MHz 105132105132 956 s
Again correct.
It will the ramp-down in 50 pulses.
Here's a capture of the SPI initialisation (expanded in the inset below right) and the pulse train from start to stable.
If you have OpenLogic Sniffer software, you can review the measurements. I've attached the .olp project. It contains all sample info.
In the sample resolution that I used, my logic analyser (a Papilio Pro FPGA board!) doesn't have enough memory to catch the full pulse train and all HET information in one shot.
Here's a capture, at slower sampling speed, of the pulse train only (click for higher image resolution):
On an oscilloscope:
Next
I assumed that my motor would start spinning, now that I have replicated SPI sequence and pulse train - and drive the nSLEEP pin correctly.
But it doesn't. I'm going to rewire the original MSP430 setup and see if I miss something.
Hang on....
edit: the reason why it wasn't working was because of the SPI settings.
I had to change the clock phase. That changes at what time the data is written (and read) relative to the clock signal.
I've attached the code composer studio project, including the HET assembly code.
Top Comments