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);
}