I am trying to use this display with an STM32F0 using SPI. I begin by setting up the peripherals using the following
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
GPIOB->MODER |= (0x2 << (2*12)) + (0x2 << (2*13)) + (0x2 << (2*15)) +
(0x1 << (2*11)) + (0x1 << (2*10));
SPI2->CR1 |= SPI_CR1_BIDIMODE + SPI_CR1_BIDIOE + SPI_CR1_MSTR + SPI_CR1_BR;
SPI2->CR2 |= SPI_CR2_SSOE + SPI_CR2_NSSP;
SPI2->CR1 |= SPI_CR1_SPE;
In other words, I enable the clock to the peripherals, enable alternate funtions for the SPI NSS
, MOSI
, and SCK
pins, as well as for the manually controlled D/CX
and RST
pins. I enable bidirectional mode and enable the SPI. I then initialize the LCD using commands adapted from Crystalfontz' Arduino example code (which I will not post to save space). However, once the initialization is done, the screen displays the following.
Clearly, this is not what I want. I attempt to fill the screen using the following functions.
void SPI_sendCommand(uint8_t command) {
CLR_RS;
while (!(SPI2->SR & SPI_SR_TXE));
SPI2->DR = command;
while (!(SPI2->SR & SPI_SR_TXE));
}
void SPI_sendData(uint8_t data) {
SET_RS;
while (!(SPI2->SR & SPI_SR_TXE));
SPI2->DR = data;
while (!(SPI2->SR & SPI_SR_TXE));
}
void setDisplayWindow(int x0, int y0, int x1, int y1) {
SPI_sendCommand(ST7789_CASET); // Column Address Set
SPI_sendData(x0>>8); // X address start:
SPI_sendData(x0); // 0 <= XS <= X
SPI_sendData(x1>>8); // X address end:
SPI_sendData(x1); // S <= XE <= X
SPI_sendCommand(ST7789_RASET); //Row address set
SPI_sendData(y0>>8); // Y address start:
SPI_sendData(y0); // 0 <= YS <= Y
SPI_sendData(y1>>8); // Y address start:
SPI_sendData(y1); // S <= YE <= Y
SPI_sendCommand(ST7789_RAMWR); //write data
}
void fillLCD(uint8_t R, uint8_t G, uint8_t B) {
setDisplayWindow(0, 0, 239, 239);
SET_RS;
for (h = 0; h < 240; h++) {
for (w = 0; w < 240; w++) {
while (!(SPI2->SR & SPI_SR_TXE));
SPI2->DR = R;
while (!(SPI2->SR & SPI_SR_TXE));
SPI2->DR = G;
while (!(SPI2->SR & SPI_SR_TXE));
SPI2->DR = B;
while (!(SPI2->SR & SPI_SR_TXE));
}
}
CLR_RS;
}
where CLR_RS
and SET_RS
clear and set the D/CX
pin, respectively. These functions do not do their job, but are almost identical to the ones in the example code. My pins are set up as follows.
1 - GND 2 - Vcc (3.3 V)
3 - Open 4 - Open
5 - GND 6 - Vcc
7 - Vcc 8 - GND
9 - PB13 (SCL) 10 - PB15 (MOSI)
11 - Open 12 - PB11 (D/CX)
13 - PB12 (NSS) 14 - GND
15 - PB10 (RST) 16 - GND
17 - Open 18 - GND
I believe the issue may be with how I write data bytes to the SPI, as commands that don't take parameters, like putting the display in sleep mode, work, while commands that take parameters, like changing the brightness, do not work. Does anyone have any idea how I can get just a solid color to display on this?