ESP32 not writing to RA8875 board via SPI.

Twist3r
Posts: 1
Joined: Thu Sep 19, 2024 12:51 pm

ESP32 not writing to RA8875 board via SPI.

Postby Twist3r » Thu Sep 19, 2024 2:16 pm

I've been trying to get my ESP32 to work with the RA8875
board that controls a TFT display but can't seem to write to
the registers. I have followed the Data Sheet in terms of CMD
sequence but still no. I can read the registers fine though. When
I read the registers I attempted to write to, they return default
values. I am using the Espressif IDF with the ESP32-WROOM 32.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#include "esp_log.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"

/* SPI configuration */
#define ESP_HOST  VSPI_HOST
#define CSO        5
#define SCLK       18
#define MISO       19
#define MOSI       23


#define SPI_TAG    "spi_protocol"

esp_err_t ret;
spi_device_handle_t spi;

/* Function declarations */
void vSpiInit(void);
void spi_write_command(uint8_t addr, uint8_t data);
void spi_read_sts(void);
void spi_read_register(uint8_t addr);

void app_main(void)
{
    vSpiInit();

    spi_read_sts();
    // Set LCD screen on
    spi_write_command(0x01, 0x80);

    // Set GPIOX on
    spi_write_command(0xC7, 0x01);

    // PW1config
    spi_write_command(0x8A, 0x8A);

    // Set PWMOut to 255
    spi_write_command(0x8B, 0xFF);

    // Select RGB565
    spi_write_command(0x10, 0x08);


	// RBG565
    // Background Color Red 5bits
    spi_write_command(0x60, 0x01F);

    // Background Color Green 6bits
    spi_write_command(0x61, 0x00);	

    // Background Color Blue 5bits
    spi_write_command(0x62, 0x14);

    while (1) {
    	//spi_read_sts();
        //spi_read_register(0x10);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void vSpiInit(void)
{
    // Configure CSO pin as output
    gpio_set_direction(CSO, GPIO_MODE_OUTPUT);
    gpio_set_level(CSO, 1); 										// Set CS high initially

    spi_bus_config_t buscfg = {
        .miso_io_num = MISO,
        .mosi_io_num = MOSI,
        .sclk_io_num = SCLK,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 4092
    };

    spi_device_interface_config_t devcfg = {
        .clock_speed_hz = 12 * 1000 * 1000, 							// 12MHz
        .mode = 0,
        .spics_io_num = CSO,
        .queue_size = 7
    };

    ret = spi_bus_initialize(VSPI_HOST, &buscfg, SPI_DMA_CH_AUTO); 	// Initialize the SPI bus
    ESP_ERROR_CHECK(ret);

    ret = spi_bus_add_device(VSPI_HOST, &devcfg, &spi); 			// Attach the Slave device to SPI bus
    ESP_ERROR_CHECK(ret);
}


void spi_write_command(uint8_t addr, uint8_t data)
{
    // First transaction: Send command (0x80 + address)
spi_transaction_t trans_desc1 = {
    .flags      = SPI_TRANS_USE_TXDATA,               				// Use tx_data for command + address
    .tx_data    = {0x80, addr},           							// Send 0x80 (command) and addr (address)
    .length     = 16,                                 				// Send 16 bits: 8 bits for 0x80 and 8 bits for addr
};

// Second transaction: Send 0x00 + data
spi_transaction_t trans_desc2 = {
    .flags      = SPI_TRANS_USE_TXDATA,               				// Use tx_data for 0x00 + data
    .tx_data    = {0x00, data},           							// Send 0x00 (no-op) and data
    .length     = 16,                                 				// Send 16 bits: 8 bits for 0x00 and 8 bits for data
};

    // Perform the first transaction (send command + address)
    gpio_set_level(CSO, 0);    										// Activate Chip Select (CS Low)
    ret = spi_device_polling_transmit(spi, &trans_desc1);  			// Send 0x80 + addr
    if (ret != ESP_OK) {
        ESP_LOGE(SPI_TAG, "SPI Command Write (0x80 + addr) failed\n");
    }
    gpio_set_level(CSO, 1);    										// Deactivate Chip Select (CS High)

    vTaskDelay(1 / portTICK_PERIOD_MS);      						// Short delay

    // Perform the second transaction (send 0x00 + data)
    gpio_set_level(CSO, 0);    										// Activate Chip Select (CS Low)
    ret = spi_device_polling_transmit(spi, &trans_desc2);  			// Send 0x00 + data
    if (ret != ESP_OK) {
        ESP_LOGE(SPI_TAG, "SPI Data Write (0x00 + data) failed\n");
    }
    gpio_set_level(CSO, 1);    										// Deactivate Chip Select (CS High)

    vTaskDelay(1 / portTICK_PERIOD_MS);      						// Short delay to ensure the transaction is complete
}


void spi_read_register(uint8_t addr) {
    uint8_t read_data;

    // Write Command (0x80 + addr) to transaction
    spi_transaction_t write_command_transaction = {
        .flags      = SPI_TRANS_USE_TXDATA,
        .tx_data    = {0x80, addr},
        .length     = 16   											// 8 bits for 0x80, 8 bits for addr
    };

    // Combined read command (0x40) and read response in one transaction
    spi_transaction_t read_transaction = {
        .flags      = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA,  // Both TX and RX
        .tx_data    = {0x40, 0x00},  								// Send the read command (0x40) followed by a dummy byte
        .rxlength   = 16,            								// Expecting 8 bits response after 8 bits command
        .length     = 16             								// Total transfer length is 16 bits (8 for command + 8 for data)
    };

    // 1. Send the write command (0x80 + addr)
    gpio_set_level(CSO, 0);    										// Activate Chip Select (CS Low)
    ret = spi_device_polling_transmit(spi, &write_command_transaction);
    if (ret != ESP_OK) {
        ESP_LOGE(SPI_TAG, "SPI Write Command failed\n");
    }
    gpio_set_level(CSO, 1);   										// Deactivate Chip Select (CS High)

    // Small delay
    vTaskDelay(1 / portTICK_PERIOD_MS);

    // 2. Send the read command (0x40) and receive the data in the same transaction
    gpio_set_level(CSO, 0);    										// Activate Chip Select (CS Low)
    ret = spi_device_polling_transmit(spi, &read_transaction);
    if (ret != ESP_OK) {
        ESP_LOGE(SPI_TAG, "SPI Read Transaction failed\n");
    }
    gpio_set_level(CSO, 1);    										// Deactivate Chip Select (CS High)

    // The response from the device will be in rx_data[1] (second byte)
    read_data = read_transaction.rx_data[1];  						// Read the second byte
    printf("Data Read 0x%x -> 0x%x\n", addr, read_data);

    // Small delay to ensure the transaction is complete
    vTaskDelay(1 / portTICK_PERIOD_MS);
}



void spi_read_sts(void){
	uint8_t read_data;

	// Write Command (0x80 + addr) to transaction
    spi_transaction_t write_command_transaction = {
        .flags      = SPI_TRANS_USE_TXDATA,
        .tx_data    = {0x80, 0x01},									// Dummy address
        .length     = 16   											// 8 bits for 0x80, 8 bits for addr
    };

	// STS combined read command (0xC0) and read response in one transaction
    spi_transaction_t read_transaction = {
        .flags      = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA,  // Both TX and RX
        .tx_data    = {0xC0, 0x00},  								// Send the status read command (0xC0) followed by a dummy byte
        .rxlength   = 16,            								// Expecting 8 bits response after 8 bits command
        .length     = 16             								// Total transfer length is 16 bits (8 for command + 8 for data)
    };

    // 1. Send the write command (0x80 + addr)
    gpio_set_level(CSO, 0);    										// Activate Chip Select (CS Low)
    ret = spi_device_polling_transmit(spi, &write_command_transaction);
    if (ret != ESP_OK) {
        ESP_LOGE(SPI_TAG, "SPI Write Command failed\n");
    }
    gpio_set_level(CSO, 1);   										// Deactivate Chip Select (CS High)

    // Small delay
    vTaskDelay(1 / portTICK_PERIOD_MS);

    // 2. Send the read command (0x40) and receive the data in the same transaction
    gpio_set_level(CSO, 0);    										// Activate Chip Select (CS Low)
    ret = spi_device_polling_transmit(spi, &read_transaction);
    if (ret != ESP_OK) {
        ESP_LOGE(SPI_TAG, "SPI Read Transaction failed\n");
    }
    gpio_set_level(CSO, 1);    										// Deactivate Chip Select (CS High)

    // The response from the device will be in rx_data[1] (second byte)
    read_data = read_transaction.rx_data[1];  						// Read the second byte
    printf("Status Read -> 0x%x\n", read_data);

    // Small delay to ensure the transaction is complete
    vTaskDelay(1 / portTICK_PERIOD_MS);
}

eriksl
Posts: 116
Joined: Thu Dec 14, 2023 3:23 pm
Location: Netherlands

Re: ESP32 not writing to RA8875 board via SPI.

Postby eriksl » Tue Oct 29, 2024 5:10 pm

Please note that the RA chips have various access methods and you need to select the proper one for any communication to succeed. In this case I guess you would need to select SPI mode, but then also select the proper sub mode, either 8bit+d/c or 9bit and then whether to use bidirectional "sda" (mosi plus miso over one wire) or miso/mosi separate. Please note that RA can't really be controlled well without feedback from the controller, so you need both miso and mosi (as opposed to the popular "generic" SPI LCD controllers).

Who is online

Users browsing this forum: Majestic-12 [Bot] and 112 guests