Read and Write registers of slave using SPI without using <SPI.h>

Hi.

I have written the following code for reading and writing into registers using SPI.
Master : Atmega328p
Slave : LIS3DH

#include <avr/io.h>
#include <avr/interrupt.h>

#define PORT_SPI    PORTB
#define DDR_SPI     DDRB
#define DD_MISO     DDB4
#define DD_MOSI     DDB3
#define DD_SS       DDB2
#define DD_SCK      DDB5
#define READ        0x80

void setup() {
  // put your setup code here, to run once:
  Serial.begin(250000);
  Serial.println("Demo started, initializing sensors");
  // AccelerometerInit();
  Serial.println("Sensors have been initialized");

  spi_init();

}

void loop()
{
  // Allocate buffer array
  //uint8_t data_buf[1];
  uint8_t c;
  // Initialize SPI
  // Send 0xFF to spi slave and read 1 byte back to the same array
  //data_buf[0] = 0xFF;
  //spi_transfer_sync(data_buf,data_buf,1);
  // Show received byte on LEDs
  //PORTC = ~data_buf[0];


  // READ

  //  PORTB &= ~(1<<PB0);      // enable  i.e. /CS low
  //  spi_fast_shift(0x30|READ);
  //  c = spi_fast_shift(0xFF);
  //  PORTB |= (1<<PB0);       // disable i.e. /CS high
  //
  //  Serial.println(c);

  // WRITE

  PORTB &= ~(1 << PB0);    // enable  i.e. /CS low
  spi_fast_shift(0x38);
  spi_fast_shift(0x15);
  PORTB |= (1 << PB0);     // disable i.e. /CS high

  delay(10);

  PORTB &= ~(1 << PB0);    // enable  i.e. /CS low
  spi_fast_shift(0x38 | READ);
  c = spi_fast_shift(0xFF);
  PORTB |= (1 << PB0);     // disable i.e. /CS high


  Serial.println(c);

  delay(1000);
}

void spi_init()
// Initialize pins for spi communication
{
  //  DDR_SPI &= ~((1<<DD_MOSI)|(1<<DD_MISO)|(1<<DD_SS)|(1<<DD_SCK));
  // Define the following pins as output
  DDR_SPI |= ((1 << DD_MOSI) | (1 << DD_SS) | (1 << DD_SCK));

  SPCR = ((1 << SPE) |            // SPI Enable
          (0 << SPIE) |           // SPI Interupt Enable
          (0 << DORD) |           // Data Order (0:MSB first / 1:LSB first)
          (1 << MSTR) |           // Master/Slave select
          (0 << SPR1) | (1 << SPR0) | // SPI Clock Rate
          (0 << CPOL) |           // Clock Polarity (0:SCK low / 1:SCK hi when idle)
          (0 << CPHA));           // Clock Phase (0:leading / 1:trailing edge sampling)

  SPSR = (1 << SPI2X);            // Double Clock Rate
}

void spi_transfer_sync (uint8_t * dataout, uint8_t * datain, uint8_t len)
// Shift full array through target device
{
  uint8_t i;
  for (i = 0; i < len; i++) {
    SPDR = dataout[i];
    while ((SPSR & (1 << SPIF)) == 0);
    datain[i] = SPDR;
  }
}

void spi_transmit_sync (uint8_t * dataout, uint8_t len)
// Shift full array to target device without receiving any byte
{
  uint8_t i;
  for (i = 0; i < len; i++) {
    SPDR = dataout[i];
    while ((SPSR & (1 << SPIF)) == 0);
  }
}

uint8_t spi_fast_shift (uint8_t data)
// Clocks only one byte to target device and returns the received one
{
  SPDR = data;
  while ((SPSR & (1 << SPIF)) == 0);
  return SPDR;
}

I am only able to successfully read or write only once. If I want to write into multiple registers or first write and then read (as in above code), I am getting absurd results.

Thank you for helping.

Why don't you use the SPI library? With your implementation you just loose speed.

I am only able to successfully read or write only once. If I want to write into multiple registers or first write and then read (as in above code), I am getting absurd results.

Please post some output.

You started UNO-I2C-LIS3DH there, but you have not continued that post.

Now, you have started UNO-SPI-LIS3DH HERE; are you sure that you will continue this post?

Actually that was for I2C, this one is for SPI.

And I got the mistake. It was with CS pin.