attiny 85 (spi,BitBanged...)

i need to have some kind of help and not sure if possible.
i want to control MCP41100, single 100K digital pots for audio with ATtiny85.
i have been reading several articles about various protocols and i just cant seem to wrap my nut-brain around the articles. the easiest one i have found was from Nick G. for SPI and/or BitBang. i understand the way it works but when i try to use code, i get several errors of undeclared variables and namespace .(Gammon Forum : Electronics : Microprocessors : SPI - Serial Peripheral Interface - for Arduino about 3/4 way down)

i either need some help to get something written, a truly easy library to use or corrections i need to make with my sketch. i know the 85's do not have a true SPI but reading the several articles, i understand it can be done to "fake" SPI.

i will basically have two push buttons on ladder to control volume up and down with a D.Pot for left and D.Pot for right.
i understand i need to select 2 SS pins (one for each D.Pot).
i understand that i put the MOSI,MISO and SCK pin numbers in the code, as described on Nick's site.

i do not understand what to do with or where to put the 'namespace' coding. with sketch i'm writing (which i did) or is it imported as a library somehow?
am i even using it correctly in my sketch, included as word doc.

can someone please assist?????????

int BS;  // value for button read
int k = 80;  // default for power up



void setup (void)
{
  tinySPI::begin ();
}  // end of setup

void loop (void)
{
  //char c;
  BS=analogRead(A3); //read which button pressed
  if (BS<160 && BS>155)  //if "UP" button pressed, raise volume
    k=k+2;

  // enable Slave Select
  digitalWrite(tinySPI::SS, LOW); 

  // send test string
  //for (const char * p = "Hello, world!" ; c = *p; p++)
  tinySPI::transfer (k); // write new value for 'k' to adjust digital pot

  // disable Slave Select
  digitalWrite(tinySPI::SS, HIGH);

  delay (100); 
  
  
  
  
if (BS<190 && BS>185)  //if "DOWN" button pressed, lower volume
    k=k-2;

  // enable Slave Select
  digitalWrite(tinySPI::SS, LOW); 

  // send test string
  //for (const char * p = "Hello, world!" ; c = *p; p++)
  tinySPI::transfer (k); // write new value for 'k' to adjust digital pot

  // disable Slave Select
  digitalWrite(tinySPI::SS, HIGH);

  delay (100);   
}  // end of loop



// Written by Nick Gammon
// March 2013

// ATMEL ATTINY45 / ARDUINO pin mappings
//
//                         +-\/-+
// RESET  Ain0 (D 5) PB5  1|    |8  Vcc
// CLK1   Ain3 (D 3) PB3  2|    |7  PB2 (D 2) Ain1  SCK  / USCK / SCL
// CLK0   Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1  MISO / DO
//                   GND  4|    |5  PB0 (D 0) pwm0  MOSI / DI / SDA
//                         +----+


namespace tinySPI 
  {

  const byte DI   = 0;  // D0, pin 5  Data In
  const byte DO   = 1;  // D1, pin 6  Data Out (this is *not* MOSI)
  const byte USCK = 2;  // D2, pin 7  Universal Serial Interface clock
  const byte SS   = 4;  // D4, pin 3  Slave Select
  
  void setup ()
    {
    digitalWrite (SS, HIGH);  // ensure SS stays high until needed
    pinMode (USCK, OUTPUT);
    pinMode (DO,   OUTPUT);
    pinMode (SS,   OUTPUT);
    pinMode (DI,   INPUT);
    USICR = bit (USIWM0);  // 3-wire mode
    }  // end of tinySPI_begin
    
  // What is happening here is that the loop executes 16 times.
  // This is because the 4-bit counter in USISR is initially zero, and then
  // toggles 16 times until it overflows, thus counting out 8 bits (16 toggles).
  // The data is valid on the clock leading edge (equivalent to CPHA == 0).
  
  byte transfer (const byte b)
    {
    USIDR = b;  // byte to output
    USISR = bit (USIOIF);  // clear Counter Overflow Interrupt Flag, set count to zero 
    do
      {
      USICR = bit (USIWM0)   // 3-wire mode
            | bit (USICS1) | bit (USICLK)  // Software clock strobe
            | bit (USITC);   // Toggle Clock Port Pin
      } while ((USISR & bit (USIOIF)) == 0);  // until Counter Overflow Interrupt Flag set
      
    return USIDR;  // return read data
    }    // end of tinySPI_transfer

  };  // end of namespace tinySPI

Moderator edit: word document replace with source in code tags

I suspect the part written by Nick was meant to be placed in a header file which is then included in your sketch.

Also, in your part of the sketch, where you put "::" it perhaps should be ".".

Paul

not sure what i did wrong the first time but looking at different web pages, it shows Nick’s namespace to be first in the sketch. i did that and it compiled fine this time. i cannot get anything to happen when push button testing with led.

my next question concerns pin connections.
is CS the same as SS? i’m understanding that it is to select the slave unit to write data to.
the namespace calls for 4 pin connections, i see 3 with D.Pot.
i have included full sketch to see the pin assignments i used in the namespace section as well how i am trying to write data to the D.Pot with button reads.
below is how i have pins connected to each other for sketch. nothing is happening

MCP41100 ATtiny85
1-CS (SS ???) - using D3 /pin 2
2-SCK -using D2/pin 7
3-SI - using D0/pin 5
4-GND
5-PA0 (pot input) - using audio pre-amp input (LM386)
6-PW0 (pot wiper) - going into tda2050 pcb
7-GND
8-+5V

// tinySPI
// Written by Nick Gammon
// March 2013

// ATMEL ATTINY45 / ARDUINO pin mappings
//
//                         +-\/-+
// RESET  Ain0 (D 5) PB5  1|    |8  Vcc
// CLK1   Ain3 (D 3) PB3  2|    |7  PB2 (D 2) Ain1  SCK  / USCK / SCL
// CLK0   Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1  MISO / DO
//                   GND  4|    |5  PB0 (D 0) pwm0  MOSI / DI / SDA
//                         +----+

namespace tinySPI 
{

  const byte DI   = 0;  // D0, pin 5  Data In
  const byte DO   = 1;  // D1, pin 6  Data Out (this is *not* MOSI)
  const byte USCK = 2;  // D2, pin 7  Universal Serial Interface clock
  const byte SS   = 3;  // D3, pin 2  Slave Select

  void begin ()
  {
    digitalWrite (SS, HIGH);  // ensure SS stays high until needed
    pinMode (USCK, OUTPUT);
    pinMode (DO,   OUTPUT);
    pinMode (SS,   OUTPUT);
    USICR = _BV (USIWM0);  // 3-wire mode
  }  // end of tinySPI_begin

  // What is happening here is that the loop executes 16 times.
  // This is because the 4-bit counter in USISR is initially zero, and then
  // toggles 16 times until it overflows, thus counting out 8 bits (16 toggles).
  // The data is valid on the clock leading edge (equivalent to CPHA == 0).

  byte transfer (const byte b)
  {
    USIDR = b;  // byte to output
    USISR = _BV (USIOIF);  // clear Counter Overflow Interrupt Flag, set count to zero 
    do
    {
      USICR = _BV (USIWM0)   // 3-wire mode
        | _BV (USICS1) | _BV (USICLK)  // Software clock strobe
          | _BV (USITC);   // Toggle Clock Port Pin
    } 
    while ((USISR & _BV (USIOIF)) == 0);  // until Counter Overflow Interrupt Flag set

    return USIDR;  // return read data
  }    // end of tinySPI_transfer

};  // end of namespace tinySPI 


#define BS A2
int k;
int BR;



void setup()
{
  tinySPI::begin();

}


void loop()
{
  BR=analogRead(BS);
  if (BR<78 && BR>74) k=k+2;

  digitalWrite(tinySPI::SS,LOW);
  tinySPI::transfer(k);
  digitalWrite(tinySPI::SS,HIGH);
  delay(100);

}

is CS the same as SS? i'm understanding that it is to select the slave unit to write data to.
the namespace calls for 4 pin connections, i see 3 with D.Pot.

CS is the same as SS. This is an output from the master and an input to the slave. The master device pulls this pin low, which causes the slave to be activated to correspond to messages.

There is 3 pins, because for your slave device the communication is one-way, therefore the MISO connection ( master-in, slave-out ) connection is not needed in this scenario. I don't know exactly how the master has to be set up for this.

It seems like a dumb idea to label the input and output pins DO and DI in that order.

There is a prominent disclaimer in that code… Data Output ( This is not MOSI ).

I can’t figure out what that means, but understanding that disclaimer might be a key thing you need to understand in order to get it to work.

thanks very much. at least you guys have pointed me in the right direction. i appreciate that.
i just need to keep taking notes and learning from the "ooops!"

There is a 3-wire version of SPI, where one data line is used, and both input and output run on the same data line.

If you google “3 wire SPI”, you can find a bunch of places where it is mentioned and described in greater or lesser detail. I suspect, but cannot tell for sure, that the Attiny implementation is performing 3-wire spi.

I learn a lot from these questions, too. What I usually learn, is that my first answer is bogus, and after I go and do some more research, I have learned something that I didn't know before.

It's really Great to be able to read them as a dialog... Most educational.. Thank You.

Doc