cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 SPI Communication Issue with RA8875 Display Controller

jlaufer
Associate II

 

I'm trying to port Adafruit's RA8875 Arduino library to work with an STM32F4 Discovery board. The SPI communication is failing during device initialization.
 
During initialization, when reading the device ID register (0x0), I expect to read 0x75 but always get 0xFF. The SPI DR register gets set to 0xFF on the first transfer and never changes.
 
1. Is my SPI configuration correct for the RA8875 (Mode 3, ~1.3MHz)?
2. Could the issue be with my SPI transfer implementation?
3. Are there any timing requirements between CS toggles and data transfers?
 
Hardware setup:
- STM32F4 Discovery Board
- Adafruit RA8875 Display Controller
- SPI1:
  - SCK: PA5
  - MISO: PA6
  - MOSI: PA7
  - CS: PA4
  - RST: PB0
 
I've tried various SPI modes and baud rates as well as adding delays between transfers and confirmed the wire connections are correct.

## SPI configuration ##

 

 static SPI_Config getSPIConfig(void)
  {
    return {
      .SPI_DeviceMode = DEVICE_MODE_MASTER,
      .SPI_Mode = SPI_MODE_3,
      .SPI_BaudRate = BR_DIV32,
      .SPIx = SPI1
    };
  }

 

## RA8875 initialization sequence ##

 

bool Adafruit_RA8875::begin(enum RA8875sizes s) {
  //....

  // Initialize CS and RST pins as outputs
  _cs.init(PP_OUTPUT_MODE, NO_PULL);
  _rst.init(PP_OUTPUT_MODE, NO_PULL);

  // write CS high and keep it high
  _cs.write(GPIO_PIN_SET);

  // write RST low then high
  _rst.write(GPIO_PIN_RESET);
  HAL_Delay(100);
  _rst.write(GPIO_PIN_SET);
  HAL_Delay(100);

  // Initialize SPI
  _spi.begin();

  uint8_t x = readReg(0);
  if (x != 0x75) {
    Error_Handler();  // This is where failure happens
    return false;
  }

  initialize();

  return true;
}

## SPI transfers ##

void Adafruit_RA8875::writeReg(uint8_t reg, uint8_t val) {
  writeCommand(reg);
  writeData(val);
}

uint8_t Adafruit_RA8875::readReg(uint8_t reg) {
  writeCommand(reg);
  return readData();
}

uint8_t Adafruit_RA8875::readData(void) {
  _cs.write(GPIO_PIN_RESET);
  _spi.begin();
  _spi.transfer(RA8875_DATAREAD);
  uint8_t x = _spi.transfer(0x0);
  _spi.end();
  _cs.write(GPIO_PIN_SET);
  return x;
}

void Adafruit_RA8875::writeCommand(uint8_t d) {
  _cs.write(GPIO_PIN_RESET);
  _spi.begin();
  _spi.transfer(RA8875_CMDWRITE);
  _spi.transfer(d);
  _spi.end();
  _cs.write(GPIO_PIN_SET);
}

uint8_t SPI::transfer(uint8_t data) {
    // Wait until TXE is set (Transmit buffer empty)
    while (!(_pSPIx->SR & SPI_SR_TXE));
    
    // Send data
    _pSPIx->DR = data;
    
    // Wait until RXNE is set (Receive buffer not empty)
    while (!(_pSPIx->SR & SPI_SR_RXNE));
    
    // Return received data
    return _pSPIx->DR;
}

void SPI::begin(void) {
    _pSPIx->CR1 |= SPI_CR1_SPE;
}

void SPI::end(void) {
    while (_pSPIx->SR & SPI_SR_BSY);  // Wait until not busy
    _pSPIx->CR1 &= ~SPI_CR1_SPE;
}

 

 
2 REPLIES 2
TDK
Guru

0xFF likely means the controller is not powered, or not correctly connected. It is the absence of a signal. Code and settings presented seem fine.

If you feel a post has answered your question, please click "Accept as Solution".
jlaufer
Associate II

I don't think it's power. There is designated 5V LDO L7805 giving power to both MCU and RA8875. Here is the logic analyzer output. Here is full source code if it helps at all.

RA8875 Log Analyzer.png