SPI with digipot and display -- CS failure? I get one or the other but not both

I'm using an ad8402 digipot (1) to control a PWM motor controller and I'd like to get motor feedback on an LED display (2). I'm using a remote control device to set the motor speed (3). I've followed the digipot tutorial (4) and alfa66's last comment in this thread (5) to setup the digipot.

When I run code that only controls the motor, it works great with the remote (press 0: stop, 3: slow, 6: medium, 9: fast) -- this is with the display wired in. The display is sharing CLK and MOSI with the digipot, although I've tried it with all the display pins separated from the digipot. The display comes with some libraries that use SPI (6).

When I run code that only operates the display (digipot in the circuit), the display shows what I want when I press those buttons.

But, when I try to combine the display and digipot code into a single program, I either get motor control or display control, depending on the order I call the those parts in setup. So I got to thinking that I'm not using CS correctly (the display and the digipot are on separate pins for CS) and that I'm really only activating the pin for the first device I communicate with in setup.

Clearly, I'm not handling CS correctly and any hints on how I can address both parts would be appreciated.

(1) Monochrome 128x32 SPI OLED graphic display : ID 661 : $17.50 : Adafruit Industries, Unique & fun DIY electronics and kits
(2) http://www.digikey.com/product-search/en?pv1=112&pv154=756&pv69=80&k=ad8402&mnonly=0&newproducts=0&ColumnSort=0&page=1&quantity=0&ptm=0&fid=0&pageSize=100
(3) Mini Remote Control : ID 389 : $4.95 : Adafruit Industries, Unique & fun DIY electronics and kits
(4) http://arduino.cc/en/Tutorial/SPIDigitalPot
(5) Problem with Arduino Tutorial "Controlling a Digital Potentiometer Using SPI" - #8 by system - LEDs and Multiplexing - Arduino Forum
(6) GitHub - adafruit/Adafruit_SSD1306: Arduino library for SSD1306 monochrome 128x64 and 128x32 OLEDs

My code -- my most recent failed attempt involved using digitalWrite to the two devices identified as "lcd" and "digipot" -- I've added the lines "//last failed try" by those, but it seems the display library handles this, so I'm only sort of repeating things:

//omitted adafruit info to save space
 
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "Adafruit_NECremote.h"
#include <SPI.h>
#include <Wire.h>

//setup digipot
//MOSI=11
//CLK=13
const int digipot = 10;  //digipot CS
const int lcd = 12;  //display CS

//setup the motor to off
byte channel=1;
byte level=255;
String velocity="default";

//setup remote
#define IRpin 4
Adafruit_NECremote remote(IRpin);

// setup display
#define OLED_MOSI  11
#define OLED_CLK   13
#define OLED_DC    8
#define OLED_CS    12
#define OLED_RESET 9
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

void setup() {
  
  Serial.begin(115200);
  Serial.println("started");

  pinMode(digipot, OUTPUT);    
  pinMode(lcd, OUTPUT);
  
  SPI.begin();
  
  // setup motor in stopped
  digitalPotWrite(channel,level);
  
  //setup display to be OK on 5v
  display.begin(SSD1306_SWITCHCAPVCC);
}

void loop() {
   
  // You can set the listen() time out to 'n' seconds
  int c = remote.listen(5);  // seconds to wait before timing out!
  Serial.println(c);

  if (c >= 0) {
    if (c == 12){
      level=255;
      velocity="stopped";
      }
    
    if (c == 18){
      level=180;
      velocity="slow";
      }
    
    if (c == 22){
      level=60;
      velocity="medium";
      }

    if (c == 26){
      level=0;
      velocity="fast";
      }

    digitalPotWrite(channel,level);
    displaySpeed(velocity);
    
    Serial.println(level);
    Serial.println(velocity);
    Serial.println(c);
    Serial.println("");
  } 
}

void digitalPotWrite(byte address, byte value){
  digitalWrite(digipot, LOW);
  digitalWrite(lcd, HIGH);  //last failed try
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(digipot, HIGH);
}

void displaySpeed(String velocity){
  digitalWrite(digipot, HIGH);    //last failed try
  digitalWrite(lcd, LOW);    //last failed try
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Level:");
  display.println(velocity);
  display.display();
  digitalWrite(lcd, HIGH);    //last failed try
}

Fix these:

#define OLED_MOSI 11 // not needed, SPI.begin sets this up
#define OLED_CLK 13// not needed, SPI.begin sets this up
#define OLED_DC 8
#define OLED_CS 12 // not needed, SPI.begin sets this up >> MISO
const int lcd = 12; //display CS

Those last two could be the issue. Try a different pin.

void digitalPotWrite(byte address, byte value){
  digitalWrite(digipot, LOW);
  digitalWrite(lcd, HIGH);  //last failed try << should already be high from LCD writes
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(digipot, HIGH);
}
void displaySpeed(String velocity){
  digitalWrite(digipot, HIGH);    //last failed try << should already be High.
  digitalWrite(lcd, LOW);    //last failed try << The library doesn't take care
  display.clearDisplay();    // of slave select itself? OLED_CS?
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Level:");
  display.println(velocity);
  display.display();
  digitalWrite(lcd, HIGH);    //last failed try
}

Solved!

The defines are needed by the display library adafruit provides IF you use software SPI for the display (which I was), so the first thing I got was an error about them being missing. But that error, and especially what you said about SPI.begin already setting up those pins, is what put me on track.

The display library goes through a few backflips before doing the transfer, and in looking at that transfer function, I saw how the hardware SPI (vs. software SPI) mimicked the code I'm using to talk with the digipot, and I got to wondering if you can't mix hardware and software SPI (I don't know that definitively, I could have just been mixing them wrong). Anyhow, I changed my code to use the optional hardware SPI method, connected the pertinent pins, and voila, motor and display worked together on the first try! I'm pretty happy!

This is the function that led me to make that adjustment:

inline void Adafruit_SSD1306::fastSPIwrite(uint8_t d) {
  if(hwSPI) {
    (void)SPI.transfer(d);
  } else {
    for(uint8_t bit = 0x80; bit; bit >>= 1) {
      *clkport &= ~clkpinmask;
      if(d & bit) *mosiport |=  mosipinmask;
      else        *mosiport &= ~mosipinmask;
      *clkport |=  clkpinmask;
    }
  }
  //*csport |= cspinmask;
}

This is my working code:

//omitted adafruit info to save space
//I'm using the adafruit products listed in my first comment
 
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "Adafruit_NECremote.h"
#include <SPI.h>
#include <Wire.h>

//pins not otherwise described
//DATA (LCD), SDI (digipot)=11
//CLK  (LCD), CLK (digipot)=13

const int digipot = 10;  //digipot CS

//setup the motor to off
byte channel=1;
byte level=255;
String velocity="default";

//setup remote
#define IRpin 3
Adafruit_NECremote remote(IRpin);

#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);

void setup() {
  
  Serial.begin(115200);
  Serial.println("started");

  pinMode(digipot, OUTPUT);    
  
  //setup display to be OK on 5v
  display.begin(SSD1306_SWITCHCAPVCC);
  
  SPI.begin();
  // setup motor in stopped
  digitalPotWrite(channel,level);
}

void loop() {
   
  // You can set the listen() time out to 'n' seconds
  int c = remote.listen(5);  // seconds to wait before timing out!
  Serial.println(c);

  if (c >= 0) {
    if (c == 12){
      level=255;
      velocity="stopped";
      }
    
    if (c == 18){
      level=180;
      velocity="slow";
      }
    
    if (c == 22){
      level=60;
      velocity="medium";
      }

    if (c == 26){
      level=0;
      velocity="fast";
      }

    digitalPotWrite(channel,level);
    displaySpeed(velocity);
    
    Serial.println(level);
    Serial.println(velocity);
    Serial.println(c);
    Serial.println("");
  } 
}

void digitalPotWrite(byte address, byte value){
  digitalWrite(digipot, LOW);
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(digipot, HIGH);
}

void displaySpeed(String velocity){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Level:");
  display.println(velocity);
  display.display();
 }

Cool.