Compré este LCD: enlace
Lamentablemente, no hay ningún esquema ni información sobre este tipo de LCD en Internet. Les pedí un esquema, pero no me respondieron.
Su controlador de chip es un HX8357 (tipo D, tipo B u otro tipo, no sé).
Estoy intentando controlarlo mediante un STM32F429 a través de DPI. Sé que debo inicializar algunos de sus registros para configurar el modo DPI. Luego conecto IM0
, IM1
y IM2
a + 3.3V (para habilitar el modo de comunicación en serie).
Leí las hojas de datos HX8357D y HX8357B y de acuerdo con ellas, WR
pin sirve como SCLK
en modo SPI, y MOSI
está deshabilitado por defecto en el modelo HX8357D, y se debe habilitar escribiendo al SETRGB
registrarse.
Quiero manejar su SPI por software (porque el diseño de la PCB parece ser incorrecto). Primero, debo asegurarme de que SPI funcione correctamente. Para hacer esto, escribí el siguiente código, para implementar el software SPI:
/*
LCD_MOSI -> PF9
LCD_MISO -> PF8
LCD_CS -> PC2
LCD_WR -> PD13
LCD_RD -> PD12
LCD_BL -> PB15
LCD_RS -> PD11
LCD_RST -> PB14
*/
#define LCD_SPI_CS_LOW() HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_RESET)
#define LCD_SPI_CS_HIGH() HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET)
#define LCD_SPI_WR_LOW() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,GPIO_PIN_RESET)
#define LCD_SPI_WR_HIGH() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,GPIO_PIN_SET)
#define LCD_SPI_RD_LOW() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_RESET)
#define LCD_SPI_RD_HIGH() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_SET)
#define LCD_SPI_MOSI_LOW() HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_RESET)
#define LCD_SPI_MOSI_HIGH() HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_SET)
#define LCD_SPI_RS_LOW() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_11,GPIO_PIN_RESET)
#define LCD_SPI_RS_HIGH() HAL_GPIO_WritePin(GPIOD,GPIO_PIN_11,GPIO_PIN_SET)
#define LCD_SPI_RST_LOW() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET)
#define LCD_SPI_RST_HIGH() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET)
#define LCD_SPI_BL_LOW() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET)
#define LCD_SPI_BL_HIGH() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET)
#define LCD_READ_MISO() HAL_GPIO_ReadPin(GPIOF,GPIO_PIN_8)
void delayUS_DWT(uint32_t us) {
/* DWT struct is defined inside the core_cm4.h file */
DWT->CTRL |= 1 ; // enable the counter
volatile uint32_t cycles = (SystemCoreClock/1000000L)*us;
volatile uint32_t start = DWT->CYCCNT;
do {
} while(DWT->CYCCNT - start < cycles);
DWT->CTRL &= ~1L ;
}
static void LCD_InitPins(void){
SPI_HandleTypeDef LcdSpi;
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable GPIOB Clock */
__HAL_RCC_GPIOB_CLK_ENABLE();
/* Enable GPIOC Clock */
__HAL_RCC_GPIOC_CLK_ENABLE();
/* Enable GPIOD Clock */
__HAL_RCC_GPIOD_CLK_ENABLE();
/* Enable GPIOF Clock */
__HAL_RCC_GPIOF_CLK_ENABLE();
/* LCD CS GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* LCD WR GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_13;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* LCD RD GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_12;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* LCD RS GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_11;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* LCD BL GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_15;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* LCD MOSI GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_9;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* LCD MISO GPIO pin configuration */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* LCD RST GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
LCD_SPI_CS_HIGH();
LCD_SPI_RS_LOW();
LCD_SPI_WR_HIGH();
LCD_SPI_MOSI_LOW();
LCD_SPI_RD_HIGH();
LCD_SPI_RST_HIGH();
LCD_SPI_BL_LOW();
}
void WriteSpi(uint8_t b){
for(uint8_t bit = 0x80; bit; bit >>= 1){
if((b) & bit){
LCD_SPI_MOSI_HIGH();
} else {
LCD_SPI_MOSI_LOW();
}
LCD_SPI_WR_LOW();
delayUS_DWT(1); // wait 1 us
LCD_SPI_WR_HIGH();
delayUS_DWT(1);
}
}
uint32_t ReadSpi32(void){
uint32_t r = 0;
for (uint8_t i=0; i<32; i++) {
LCD_SPI_WR_LOW();
delayUS_DWT(1);
LCD_SPI_WR_HIGH();
delayUS_DWT(1);
r <<= 1;
if (LCD_READ_MISO() == GPIO_PIN_SET){
r |= 0x1;
}
}
return r ;
}
void writeCommand(uint8_t c) {
LCD_SPI_RS_LOW();
WriteSpi(c);
LCD_SPI_RS_HIGH();
}
uint32_t readcommand32(uint8_t command) {
LCD_SPI_RS_LOW();
WriteSpi(command);
LCD_SPI_RS_HIGH();
return ReadSpi32();
}
Probé el siguiente código (asumiendo que se utilizó el HX8357D):
void LCD_Init(void)
{
uint32_t res = 0;
LCD_InitPins();
LCD_SPI_BL_HIGH(); // Turn on backlight
LCD_SPI_RST_LOW(); // Do a hardware reset
HAL_Delay(1); // 1 ms
LCD_SPI_RST_HIGH();
HAL_Delay(1);
LCD_SPI_CS_LOW(); // "A falling edge on CSX enables the serial interface and indicates the start of data transmission."
writeCommand(HX8357D_SWRESET); // DO a software reset
LCD_SPI_CS_HIGH();
HAL_Delay(1);
LCD_SPI_CS_LOW();
writeCommand(HX8357D_SETC); // These sequence data must be written to enable other commands.
WriteSpi(0xFF);
WriteSpi(0x83);
WriteSpi(0x57);
LCD_SPI_CS_HIGH();
HAL_Delay(1);
LCD_SPI_CS_LOW();
writeCommand(HX8357D_SETRGB);
WriteSpi(0xE3); //enable SDO pin as MISO!
WriteSpi(0x0);
WriteSpi(0x06);
WriteSpi(0x06);
LCD_SPI_CS_HIGH();
HAL_Delay(1);
LCD_SPI_CS_LOW();
res = readcommand32(HX8357D_GETICID); // 'res' must be 0x99 (or 0x00009900) according to the datasheet (HIMAX_ID)
LCD_SPI_CS_HIGH();
.
.
.
También, probé el código a continuación, asumiendo que se utilizará el HX8357B:
void LCD_Init(void)
{
uint32_t res = 0;
LCD_InitPins();
LCD_SPI_BL_HIGH(); // Turn on backlight
LCD_SPI_RST_LOW(); // Do a hardware reset
HAL_Delay(1); // 1 ms
LCD_SPI_RST_HIGH();
HAL_Delay(1);
LCD_SPI_CS_LOW(); // "A falling edge on CSX enables the serial interface and indicates the start of data transmission."
writeCommand(HX8357B_SWRESET); // DO a software reset
LCD_SPI_CS_HIGH();
HAL_Delay(1);
LCD_SPI_CS_LOW();
writeCommand(HX8357B_SETRGB);
WriteSpi(0x00); //Ensure that 'SDA_EN' is cleared
LCD_SPI_CS_HIGH();
HAL_Delay(1);
LCD_SPI_CS_LOW();
res = readcommand32(HX8357B_GETDEVICEID); // 'res' must be 0x628357FF according to the datasheet [Get Device ID (BFh)]
LCD_SPI_CS_HIGH();
.
.
.
Pero la variable res
es 0x00000000 en ambos.
¿Hay algún error en el software SPI?
Gracias de antemano.