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.