problem with SPI

Hi all,
I'm trying to utilize e-paper display to present image on screen.
For reason I don't understand the SPI is not working as expected:
I've connected the clock to D13, the MOSI(EPD data-in) to D11 and CS to D7. These are the standard pins for UNO SPI.

When running the code, first command is transferred, but on second command the program is stuck and not running anymore.
I suspect I configured something wrong, could someone please give it a look?

#include"Ap_29demo.h"
#include "SPI.h"

//IO settings
int BUSY_Pin = 4;
int RES_Pin = 5;
int DC_Pin = 6;

int CS_Pin = 7; //CS
int SCK_Pin = 13; //SCLK
int SDI_Pin = 11; //MOSI

////////FUNCTIONS//////
void EPD_WriteDATA(uint8_t command);
void EPD_WriteCMD(uint8_t command);

//EPD
void EPD_init(void);
void PIC_display(const uint8_t* picData_BW, const uint8_t* picData_COLOR);
void PIC_displayClean(void);
void EPD_sleep(void);
void EPD_refresh(void);
void EPD_checkStatus(void);

void setup() {
  Serial.begin(9600);
  pinMode(BUSY_Pin, INPUT);

  digitalWrite(RES_Pin, HIGH);
  pinMode(RES_Pin, OUTPUT);
  digitalWrite(RES_Pin, LOW);
  delay(1000);
  digitalWrite(RES_Pin, HIGH);
  delay(1000);

  digitalWrite(DC_Pin, HIGH);
  pinMode(DC_Pin, OUTPUT);

  digitalWrite(CS_Pin, HIGH);
  pinMode(CS_Pin, OUTPUT);

  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
  //SPI.endTransaction();

  EPD_init(); //EPD init
  Serial.print("EPD initialized");
}

void loop() {

  PIC_displayClean();
  //EPD_refresh();//EPD_refresh
  PIC_display(gImage_black1, gImage_red1); //EPD_picture1
  EPD_refresh();//EPD_refresh
  PIC_displayClean();
  EPD_refresh();//EPD_refresh
  EPD_sleep();//EPD_sleep
}

//////////////////////SPI///////////////////////////////////

void EPD_WriteCMD(uint8_t command)
{
  digitalWrite(CS_Pin, LOW);//command write
  Serial.println("EPD_WriteCMD CS_Pin LOW");
  
  digitalWrite(DC_Pin, LOW);
  Serial.println("EPD_WriteCMD DC_Pin LOW");
  
  SPI.transfer(command);
  Serial.print("EPD_WriteCMD Command: ");
  Serial.println(command);
  
  digitalWrite(CS_Pin, HIGH);
  Serial.println("EPD_WriteCMD CS_Pin HIGH");
  
  Serial.println();
}

void EPD_WriteDATA(uint8_t command)
{
  digitalWrite(CS_Pin, LOW);//data write
  Serial.println("EPD_WriteDATA CS_Pin LOW");
  
  digitalWrite(DC_Pin, HIGH);
  Serial.println("EPD_WriteDATA DC_Pin HIGH");
  
  SPI.transfer(command);
  Serial.print("EPD_WriteDATA Data: ");
  Serial.println(command);
  
  digitalWrite(CS_Pin, HIGH);
  Serial.println("EPD_WriteCMD CS_Pin HIGH");
  
  Serial.println();
}

/////////////////EPD settings Functions/////////////////////

void EPD_init(void)
{
  unsigned char HRES = 0x98;//152
  unsigned char VRES_byte1 = 0x00;
  unsigned char VRES_byte2 = 0x98;//152

  EPD_WriteCMD(0x06);         //boost soft start
  EPD_WriteDATA(0x17);   //A
  EPD_WriteDATA(0x17);   //B
  EPD_WriteDATA(0x17);   //C
  EPD_WriteCMD(0x04);
  EPD_checkStatus();

  EPD_WriteCMD(0x00);     //panel setting
  EPD_WriteDATA(0x0f);    //LUT from OTP£¬160x296
  EPD_WriteDATA(0x0d);    //VCOM to 0V fast

  EPD_WriteCMD(0x61);     //resolution setting
  EPD_WriteDATA(HRES);
  EPD_WriteDATA(VRES_byte1);
  EPD_WriteDATA(VRES_byte2);

  EPD_WriteCMD(0X50);     //VCOM AND DATA INTERVAL SETTING
  EPD_WriteDATA(0x77);    //WBmode:VBDF 17|D7 VBDW 97 VBDB 57   WBRmode:VBDF F7 VBDW 77 VBDB 37  VBDR B7
}

void EPD_refresh(void)
{
  EPD_WriteCMD(0x12);     //DISPLAY REFRESH
  delay(100);          //!!!The delay here is necessary, 200uS at least!!!
  EPD_checkStatus();
}

void EPD_sleep(void)
{
  EPD_WriteCMD(0X50);
  EPD_WriteDATA(0xf7);

  EPD_WriteCMD(0X02);   //power off
  EPD_checkStatus();    //need to add
}

void PIC_display(const uint8_t* picData_BW, const uint8_t* picData_COLOR)
{
  unsigned int i;
  unsigned int j;

  EPD_WriteCMD(0x10);        //Transfer BW data
  for (i = 0; i < 2888; i++)
    EPD_WriteDATA(pgm_read_byte(&picData_BW[i]));

  EPD_WriteCMD(0x13);        //Transfer Yellow data
  for (i = 0; i < 2888; i++)
    EPD_WriteDATA(pgm_read_byte(&picData_COLOR[i]));
}

void PIC_displayClean(void)
{
  unsigned int i;

  EPD_WriteCMD(0x10);        //Transfer BW data
  for (i = 0; i < 2888; i++)
    EPD_WriteDATA(0xff);

  EPD_WriteCMD(0x13);        //Transfer Yellow data
  for (i = 0; i < 2888; i++)
    EPD_WriteDATA(0xff);
}

void EPD_checkStatus(void)
{
  unsigned char busy;
  while (1) {
    if (digitalRead(BUSY_Pin) == HIGH)
      break;
    delay(1);
  }
}
//////////////////////////////////END/////////////////////////////////////////

You should read http://www.gammon.com.au/spi.

There is no SPI.begin, your transaction is crap.

There is no SPI.begin() in your code~~, you are messing with CS yourself.~~*

* That seems to be okay but it is most of the time hidden inside a class using SPI.

You are correct. Thanks for you'r comment

You should make pin 10 an output to get master SPI behaviour.
But that was already discussed in the provided link. :wink:

There are no relationship issues in my case, controller is master; EPDs and RF transceiver are slaves.
EPDs don't support any MISO functionality and RF transceiver have D10 all for it self :smiley:

misha782:
There are no relationship issues in my case, controller is master;

Pin 10 of the Arduino is the SS line - so does this mean you have to use it for the peripheral SS line? Or should it be kept high?
The answer (from the Atmega documentation) is that the SS line (pin 10) must be configured as an output (regardless of what value is on it).
If configured as an output the Arduino ignores the value on that line, and thus the SPI hardware will not be put into slave mode.

I had success with following the second quote, easiest way was to use pin 10 as CS.