element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Industrial Automation
  • Technologies
  • More
Industrial Automation
Blog Stepper Motor Control with Hercules High-End Timer - Part 6: Hercules RM57 SPI
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Industrial Automation to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 9 Jun 2017 6:39 PM Date Created
  • Views 1349 views
  • Likes 2 likes
  • Comments 2 comments
  • stepper_motor
  • boosterpack
  • texas_instrutments
  • spi
  • automotive
  • rm57
  • hercules
  • launchpad
  • safety
Related
Recommended

Stepper Motor Control with Hercules High-End Timer - Part 6: Hercules RM57 SPI

Jan Cumps
Jan Cumps
9 Jun 2017

I'm trying to control an unknown stepper motor with the high-end timer (NHET) module of a Texas Instruments Hercules microcontroller

image

I got a freebie from TI almost a year ago. An unknown 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 6th blog I port the MSP40 SPI commands for the DRV8711 to the Hercules RM57 safety microcontroller..

 

This post shows that even with very different hardware, you can often reuse big chunks of code.

In this case, the DRV8711 register definitions serve me very well.

 

Big SPI differences between Hercules Controller and MSP430, Little Impact

SPI is SPI. In the example here where we use SPI to set the registers of the DRV8711, all logic to define the register values can be copied.

 

One of the examples is the DRV8711 Control register:

 

// CTRL Register
struct CTRL_Register
{
  uint16_t Address; // bits 14-12
  uint16_t DTIME; // bits 11-10
  uint16_t ISGAIN; // bits 9-8
  uint16_t EXSTALL; // bit 7
  uint16_t MODE; // bits 6-3
  uint16_t RSTEP; // bit 2
  uint16_t RDIR; // bit 1
  uint16_t ENBL; // bit 0
};

 

The choice has been made for readability, not code size. We're spending 8 integer locations to store info that needs to be contained in a 16 bit value.

Not efficient for code size, but I don't mind. It makes understanding and debugging the application easy.

You can always check the values of a particular subset of the register without having to think too much.

If you need the space later, this can be replaced by a single integer per register, and setter + getter functions that use masking, ANDing and ORing to set the right bits.

 

When setting the final value for communication, the different parts of the register get combined. I translated this part to fit everything in a single integer:

 

    uint32_t data;

    // Write CTRL Register
    data = REGWRITE | (G_CTRL_REG.Address << 12) | (G_CTRL_REG.DTIME << 10) | (G_CTRL_REG.ISGAIN << 8) |(G_CTRL_REG.EXSTALL << 7) | (G_CTRL_REG.MODE << 3) | (G_CTRL_REG.RSTEP << 2) | (G_CTRL_REG.RDIR << 1) | (G_CTRL_REG.ENBL);
    SPI_DRV8711_Write(data);

 

original code on the MSP430:

 

    unsigned char dataHi = 0x00;
    unsigned char dataLo = 0x00;


    // Write CTRL Register
    dataHi = REGWRITE | (G_CTRL_REG.Address << 4) | (G_CTRL_REG.DTIME << 2) | (G_CTRL_REG.ISGAIN);
    dataLo = (G_CTRL_REG.EXSTALL << 7) | (G_CTRL_REG.MODE << 3) | (G_CTRL_REG.RSTEP << 2) | (G_CTRL_REG.RDIR << 1) | (G_CTRL_REG.ENBL);
    SPI_DRV8711_ReadWrite(dataHi, dataLo);

 

 

With the Hercules, you get a GUI to configure the modules and registers. A nice solution that helps to master the (very complex!) peripherals of this family.

The GUI is non-intrusive and supports round-trip design. You can override the settings in code. If done properly, you can keep on using the GUI and the code changes interactively.

Here's how you set the SPI bit width and speed:

image

 

There's also a screen where you can fine-tune the timings within a SPI communication burst:

image

 

When performing the communications, these settings can be used to do unbuffered (upper part of screen capture) and buffered (lower part) SPI.

image

 

The upper part exchanges one  16-bit value (in our case, because we've defined a Data Format 0 with bit size ).

 

In the lower part, we can exchange 8 16-bit values in a single shot.

The Hercules off-loads the work to the SPI module.

The ARM controller can do different things in the meantime.

 

You can see that I haven't selected a SPI CHIP Select. That's because the Stepper Motor BoosterPack doesn't have it's CS pin on a SPI capable pin.

Don't ask me why. If only they moved it to the free pin above, it would be OK - that's a default CS pin for BoosterPacks. Don't call me. Call TI.

 

Solving Incompatible Chip Select

Easy (in our case. Less easy when dealing with a big chunk of buffered data. In that scenario I would change the hardware).

 

As told before, the CS pin on the boosterpack isn't matching a CS of the LaunchPad Standard. So we have to provide the CS ourselves.

The first thing to do is tell the SPI module to not set a CS.

image

 

From that moment on, the CS decision is up to your own firmware.

The DRV8711 CS matches the RM57 GIOB[2] pin.

So I have to do a few things

. First is to set this as a GIO output pin:

image

 

Once we've called gioInit(), this pin can be programmed.

The DRV8711, ignorant of what's common on SPI modules, expects the CS to be high when active.

void SPI_DRV8711_Write(uint16_t data) {
    gioSetBit(gioPORTB, 2, 1); // manual CS high
    mibspiSetData(mibspiREG3, 0, &data);
    mibspiTransfer(mibspiREG3, 0 );
    while(!(mibspiIsTransferComplete(mibspiREG3, 0))) {
    }
    gioSetBit(gioPORTB, 2, 0); // manual CS low
}

 

The code above bitbangs the CS high before ommunication, low after.

It works. The downside is that the ARM core needs to do the activity.

If the BoosterPack would be fully compatible, the controller would be free for any other activity once it informed the SPI module of the location and size of data ..

The while loop would be unnecessary. We'd just call the transfer module and go on doing things that matter...

Again, that's not an issue with the Hercules controller or the DRV8711 chip. It's because the way the BoosterPack routes it. Call TI.

In your own design, you'd route this DRV8711 pin to a MinSPI3 CS pin (there's 5 of them,so choice galore).

 

The excellent news is that everything works. I've replicated the code that initialises the DRV8711 from the MSP430, and the Logic Analyzer capture is fully compatible:

 

void WriteAllRegisters() {
    uint32_t data;

    // Write CTRL Register
    data = REGWRITE | (G_CTRL_REG.Address << 12) | (G_CTRL_REG.DTIME << 10) | (G_CTRL_REG.ISGAIN << 8) |(G_CTRL_REG.EXSTALL << 7) | (G_CTRL_REG.MODE << 3) | (G_CTRL_REG.RSTEP << 2) | (G_CTRL_REG.RDIR << 1) | (G_CTRL_REG.ENBL);
    SPI_DRV8711_Write(data);

    // Write TORQUE Register
    data = REGWRITE | (G_TORQUE_REG.Address << 12) | (G_TORQUE_REG.SIMPLTH << 8) | G_TORQUE_REG.TORQUE;
    SPI_DRV8711_Write(data);

    // Write OFF Register
    data = REGWRITE | (G_OFF_REG.Address << 12) | (G_OFF_REG.PWMMODE << 8) | G_OFF_REG.TOFF;
    SPI_DRV8711_Write(data);

    // Write BLANK Register
    data = REGWRITE | (G_BLANK_REG.Address << 12) | (G_BLANK_REG.ABT << 8) | G_BLANK_REG.TBLANK;
    SPI_DRV8711_Write(data);

    // Write DECAY Register
    data = REGWRITE | (G_DECAY_REG.Address << 12) | (G_DECAY_REG.DECMOD << 8) | G_DECAY_REG.TDECAY;
    SPI_DRV8711_Write(data);

    // Write STALL Register
    data = REGWRITE | (G_STALL_REG.Address << 12) | (G_STALL_REG.VDIV << 10) | (G_STALL_REG.SDCNT << 8) | G_STALL_REG.SDTHR;
    SPI_DRV8711_Write(data);

    // Write DRIVE Register
    data = REGWRITE | (G_DRIVE_REG.Address << 12) | (G_DRIVE_REG.IDRIVEP << 10) | (G_DRIVE_REG.IDRIVEN << 8) | (G_DRIVE_REG.TDRIVEP << 6) | (G_DRIVE_REG.TDRIVEN << 4) | (G_DRIVE_REG.OCPDEG << 2) | (G_DRIVE_REG.OCPTH);
    SPI_DRV8711_Write(data);

    // Write STATUS Register
    data = REGWRITE | (G_STATUS_REG.Address << 12) | (G_STATUS_REG.STDLAT << 7) | (G_STATUS_REG.STD << 6) | (G_STATUS_REG.UVLO << 5) | (G_STATUS_REG.BPDF << 4) | (G_STATUS_REG.APDF << 3) | (G_STATUS_REG.BOCP << 2) | (G_STATUS_REG.AOCP << 1) | (G_STATUS_REG.OTS);
    SPI_DRV8711_Write(data);
}

 

Protocol Analyser capture:

 

image

image

 

That's perfect for this application. There's room for optimisation, but let's only do that if needed. Any changes make comparison with the original MSP430 example more complex ..

 

For the mere mortal, this may seem to be a small step. For the down-to-earth ones: we can now focus on the core problem - creating a perfect PWM signal to drive the stepper.

 

Related Blog
Part 1: Hardware Overview
Part 2: Stepper Controller and MSP430 Firmware
Part 3: SPI Commands and Pulse Control
Part 4: Analyse MSP430 PWM Step Signal
Part 5: Hercules RM57 Hardware Provisioning
Part 6: Hercules RM57 SPI
Part 7: HET Assembly Language Test
Part 8: HET Based Pulse Train Output
  • Sign in to reply

Top Comments

  • DAB
    DAB over 8 years ago +1
    Great job Jan. From small steps great journeys can be made. DAB
  • Jan Cumps
    Jan Cumps over 8 years ago in reply to DAB

    Thank you Don.

    I'm still preparing for the big journey. My MSP430 and Hercules timer skills are not up to the mark yet.

    I'm trying to use this exercise to make the jump.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 8 years ago

    Great job Jan.

     

    From small steps great journeys can be made.

     

    DAB

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube