Merge pull request #1137 from kwagyeman/kwabena/clean_lcd_spi

Fix issues with F7 LCD triple buffering
This commit is contained in:
Ibrahim Abd Elkader 2021-01-25 02:56:58 +02:00 committed by GitHub
commit 953c23965c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -67,7 +67,7 @@ static int lcd_refresh = 0;
static int lcd_intensity = 0; static int lcd_intensity = 0;
#ifdef OMV_SPI_LCD_CONTROLLER #ifdef OMV_SPI_LCD_CONTROLLER
DMA_HandleTypeDef spi_tx_dma = {}; static DMA_HandleTypeDef spi_tx_dma = {};
static volatile enum { static volatile enum {
SPI_TX_CB_IDLE, SPI_TX_CB_IDLE,
@ -99,7 +99,7 @@ static void spi_config_deinit()
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
} }
void spi_lcd_callback(SPI_HandleTypeDef *hspi); static void spi_lcd_callback(SPI_HandleTypeDef *hspi);
static void spi_config_init(int w, int h, int refresh_rate, bool triple_buffer, bool bgr) static void spi_config_init(int w, int h, int refresh_rate, bool triple_buffer, bool bgr)
{ {
@ -198,7 +198,11 @@ static void spi_config_init(int w, int h, int refresh_rate, bool triple_buffer,
static bool spi_tx_cb_state_on[FRAMEBUFFER_COUNT] = {}; static bool spi_tx_cb_state_on[FRAMEBUFFER_COUNT] = {};
void spi_lcd_callback(SPI_HandleTypeDef *hspi) static const uint8_t display_off[] = {0x28};
static const uint8_t display_on[] = {0x29};
static const uint8_t memory_write[] = {0x2C};
static void spi_lcd_callback(SPI_HandleTypeDef *hspi)
{ {
if (lcd_type == LCD_SHIELD) { if (lcd_type == LCD_SHIELD) {
static uint16_t *spi_tx_cb_state_memory_write_addr = NULL; static uint16_t *spi_tx_cb_state_memory_write_addr = NULL;
@ -208,27 +212,27 @@ void spi_lcd_callback(SPI_HandleTypeDef *hspi)
switch (spi_tx_cb_state) { switch (spi_tx_cb_state) {
case SPI_TX_CB_MEMORY_WRITE_CMD: { case SPI_TX_CB_MEMORY_WRITE_CMD: {
if (!spi_tx_cb_state_on[framebuffer_head]) { if (!spi_tx_cb_state_on[framebuffer_head]) {
spi_tx_cb_state = SPI_TX_CB_DISPLAY_OFF;
framebuffer_tail = framebuffer_head;
OMV_SPI_LCD_CS_HIGH(); OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_ON(); OMV_SPI_LCD_RS_ON();
spi_tx_cb_state = SPI_TX_CB_DISPLAY_OFF;
framebuffer_tail = framebuffer_head;
OMV_SPI_LCD_CS_LOW(); OMV_SPI_LCD_CS_LOW();
HAL_SPI_Transmit_IT(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t []) {0x28}, 1); // display off HAL_SPI_Transmit_IT(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t *) display_off, sizeof(display_off));
} else { } else {
OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_ON();
spi_tx_cb_state = SPI_TX_CB_MEMORY_WRITE; spi_tx_cb_state = SPI_TX_CB_MEMORY_WRITE;
spi_tx_cb_state_memory_write_addr = framebuffers[framebuffer_head]; spi_tx_cb_state_memory_write_addr = framebuffers[framebuffer_head];
spi_tx_cb_state_memory_write_count = lcd_width * lcd_height; spi_tx_cb_state_memory_write_count = lcd_width * lcd_height;
spi_tx_cb_state_memory_write_first = true; spi_tx_cb_state_memory_write_first = true;
framebuffer_tail = framebuffer_head; framebuffer_tail = framebuffer_head;
OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_ON();
OMV_SPI_LCD_CS_LOW(); OMV_SPI_LCD_CS_LOW();
// When starting the interrupt chain the first HAL_SPI_Transmit_IT is not executed // When starting the interrupt chain the first HAL_SPI_Transmit_IT is not executed
// in interrupt context. So, disable interrupts for the first HAL_SPI_Transmit_IT so // in interrupt context. So, disable interrupts for the first HAL_SPI_Transmit_IT so
// that it completes first and unlocks the SPI bus before allowing the interrupt // that it completes first and unlocks the SPI bus before allowing the interrupt
// it causes to trigger starting the interrupt chain. // it causes to trigger starting the interrupt chain.
uint32_t irq_state = disable_irq(); uint32_t irq_state = disable_irq();
HAL_SPI_Transmit_IT(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t []) {0x2C}, 1); // memory write HAL_SPI_Transmit_IT(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t *) memory_write, sizeof(memory_write));
enable_irq(irq_state); enable_irq(irq_state);
} }
break; break;
@ -240,10 +244,9 @@ void spi_lcd_callback(SPI_HandleTypeDef *hspi)
spi_tx_cb_state_memory_write_addr += count; spi_tx_cb_state_memory_write_addr += count;
spi_tx_cb_state_memory_write_count -= count; spi_tx_cb_state_memory_write_count -= count;
if (spi_tx_cb_state_memory_write_first) { if (spi_tx_cb_state_memory_write_first) {
spi_tx_cb_state_memory_write_first = false;
OMV_SPI_LCD_CS_HIGH(); OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_OFF(); OMV_SPI_LCD_RS_OFF();
OMV_SPI_LCD_CS_LOW(); spi_tx_cb_state_memory_write_first = false;
OMV_SPI_LCD_CONTROLLER->spi->Init.DataSize = SPI_DATASIZE_16BIT; OMV_SPI_LCD_CONTROLLER->spi->Init.DataSize = SPI_DATASIZE_16BIT;
#if defined(MCU_SERIES_H7) #if defined(MCU_SERIES_H7)
OMV_SPI_LCD_CONTROLLER->spi->Instance->CFG1 = (OMV_SPI_LCD_CONTROLLER->spi->Instance->CFG1 & ~SPI_CFG1_DSIZE_Msk) | SPI_DATASIZE_16BIT; OMV_SPI_LCD_CONTROLLER->spi->Instance->CFG1 = (OMV_SPI_LCD_CONTROLLER->spi->Instance->CFG1 & ~SPI_CFG1_DSIZE_Msk) | SPI_DATASIZE_16BIT;
@ -252,11 +255,14 @@ void spi_lcd_callback(SPI_HandleTypeDef *hspi)
#elif defined(MCU_SERIES_F4) #elif defined(MCU_SERIES_F4)
OMV_SPI_LCD_CONTROLLER->spi->Instance->CR1 = (OMV_SPI_LCD_CONTROLLER->spi->Instance->CR1 & ~SPI_CR1_DFF_Msk) | SPI_DATASIZE_16BIT; OMV_SPI_LCD_CONTROLLER->spi->Instance->CR1 = (OMV_SPI_LCD_CONTROLLER->spi->Instance->CR1 & ~SPI_CR1_DFF_Msk) | SPI_DATASIZE_16BIT;
#endif #endif
OMV_SPI_LCD_CS_LOW();
} }
HAL_SPI_Transmit_DMA(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t *) addr, count); HAL_SPI_Transmit_DMA(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t *) addr, count);
break; break;
} }
case SPI_TX_CB_DISPLAY_ON: { case SPI_TX_CB_DISPLAY_ON: {
OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_ON();
spi_tx_cb_state = SPI_TX_CB_MEMORY_WRITE_CMD; spi_tx_cb_state = SPI_TX_CB_MEMORY_WRITE_CMD;
OMV_SPI_LCD_CONTROLLER->spi->Init.DataSize = SPI_DATASIZE_8BIT; OMV_SPI_LCD_CONTROLLER->spi->Init.DataSize = SPI_DATASIZE_8BIT;
#if defined(MCU_SERIES_H7) #if defined(MCU_SERIES_H7)
@ -266,15 +272,13 @@ void spi_lcd_callback(SPI_HandleTypeDef *hspi)
#elif defined(MCU_SERIES_F4) #elif defined(MCU_SERIES_F4)
OMV_SPI_LCD_CONTROLLER->spi->Instance->CR1 = (OMV_SPI_LCD_CONTROLLER->spi->Instance->CR1 & ~SPI_CR1_DFF_Msk) | SPI_DATASIZE_8BIT; OMV_SPI_LCD_CONTROLLER->spi->Instance->CR1 = (OMV_SPI_LCD_CONTROLLER->spi->Instance->CR1 & ~SPI_CR1_DFF_Msk) | SPI_DATASIZE_8BIT;
#endif #endif
OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_ON();
OMV_SPI_LCD_CS_LOW(); OMV_SPI_LCD_CS_LOW();
HAL_SPI_Transmit_IT(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t []) {0x29}, 1); // display on HAL_SPI_Transmit_IT(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t *) display_on, sizeof(display_on));
break; break;
} }
case SPI_TX_CB_DISPLAY_OFF: { case SPI_TX_CB_DISPLAY_OFF: {
spi_tx_cb_state = SPI_TX_CB_IDLE;
OMV_SPI_LCD_CS_HIGH(); OMV_SPI_LCD_CS_HIGH();
spi_tx_cb_state = SPI_TX_CB_IDLE;
break; break;
} }
default: { default: {
@ -323,7 +327,7 @@ static void spi_lcd_display(image_t *src_img, int dst_x_start, int dst_y_start,
OMV_SPI_LCD_RS_ON(); OMV_SPI_LCD_RS_ON();
OMV_SPI_LCD_CS_LOW(); OMV_SPI_LCD_CS_LOW();
HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t []) {0x2C}, 1, HAL_MAX_DELAY); // memory write HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t *) memory_write, sizeof(memory_write), HAL_MAX_DELAY); // memory write
OMV_SPI_LCD_CS_HIGH(); OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_OFF(); OMV_SPI_LCD_RS_OFF();
@ -364,7 +368,7 @@ static void spi_lcd_display(image_t *src_img, int dst_x_start, int dst_y_start,
OMV_SPI_LCD_RS_ON(); OMV_SPI_LCD_RS_ON();
OMV_SPI_LCD_CS_LOW(); OMV_SPI_LCD_CS_LOW();
HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t []) {0x29}, 1, HAL_MAX_DELAY); // display on HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t *) display_on, sizeof(display_on), HAL_MAX_DELAY);
OMV_SPI_LCD_CS_HIGH(); OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_OFF(); OMV_SPI_LCD_RS_OFF();
@ -418,7 +422,7 @@ static void spi_lcd_clear()
if (!lcd_triple_buffer) { if (!lcd_triple_buffer) {
OMV_SPI_LCD_RS_ON(); OMV_SPI_LCD_RS_ON();
OMV_SPI_LCD_CS_LOW(); OMV_SPI_LCD_CS_LOW();
HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t []) {0x28}, 1, HAL_MAX_DELAY); // display off HAL_SPI_Transmit(OMV_SPI_LCD_CONTROLLER->spi, (uint8_t *) display_off, sizeof(display_off), HAL_MAX_DELAY);
OMV_SPI_LCD_CS_HIGH(); OMV_SPI_LCD_CS_HIGH();
OMV_SPI_LCD_RS_OFF(); OMV_SPI_LCD_RS_OFF();
} else { } else {
@ -1681,6 +1685,7 @@ STATIC const mp_rom_map_elem_t globals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_lcd) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_lcd) },
{ MP_ROM_QSTR(MP_QSTR_LCD_NONE), MP_ROM_INT(LCD_NONE) }, { MP_ROM_QSTR(MP_QSTR_LCD_NONE), MP_ROM_INT(LCD_NONE) },
{ MP_ROM_QSTR(MP_QSTR_LCD_SHIELD), MP_ROM_INT(LCD_SHIELD) }, { MP_ROM_QSTR(MP_QSTR_LCD_SHIELD), MP_ROM_INT(LCD_SHIELD) },
#ifdef OMV_DVI_PRESENT
{ MP_ROM_QSTR(MP_QSTR_LCD_DISPLAY), MP_ROM_INT(LCD_DISPLAY) }, { MP_ROM_QSTR(MP_QSTR_LCD_DISPLAY), MP_ROM_INT(LCD_DISPLAY) },
{ MP_ROM_QSTR(MP_QSTR_LCD_DISPLAY_WITH_HDMI), MP_ROM_INT(LCD_DISPLAY_WITH_HDMI) }, { MP_ROM_QSTR(MP_QSTR_LCD_DISPLAY_WITH_HDMI), MP_ROM_INT(LCD_DISPLAY_WITH_HDMI) },
{ MP_ROM_QSTR(MP_QSTR_LCD_DISPLAY_ONLY_HDMI), MP_ROM_INT(LCD_DISPLAY_ONLY_HDMI) }, { MP_ROM_QSTR(MP_QSTR_LCD_DISPLAY_ONLY_HDMI), MP_ROM_INT(LCD_DISPLAY_ONLY_HDMI) },
@ -1702,6 +1707,7 @@ STATIC const mp_rom_map_elem_t globals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_UXGA), MP_ROM_INT(LCD_DISPLAY_UXGA) }, { MP_ROM_QSTR(MP_QSTR_UXGA), MP_ROM_INT(LCD_DISPLAY_UXGA) },
{ MP_ROM_QSTR(MP_QSTR_HD), MP_ROM_INT(LCD_DISPLAY_HD) }, { MP_ROM_QSTR(MP_QSTR_HD), MP_ROM_INT(LCD_DISPLAY_HD) },
{ MP_ROM_QSTR(MP_QSTR_FHD), MP_ROM_INT(LCD_DISPLAY_FHD) }, { MP_ROM_QSTR(MP_QSTR_FHD), MP_ROM_INT(LCD_DISPLAY_FHD) },
#endif
#ifdef OMV_TOUCH_PRESENT #ifdef OMV_TOUCH_PRESENT
{ MP_ROM_QSTR(MP_QSTR_LCD_GESTURE_MOVE_UP), MP_ROM_INT(PY_LCD_TOUCH_GESTURE_MOVE_UP) }, { MP_ROM_QSTR(MP_QSTR_LCD_GESTURE_MOVE_UP), MP_ROM_INT(PY_LCD_TOUCH_GESTURE_MOVE_UP) },
{ MP_ROM_QSTR(MP_QSTR_LCD_GESTURE_MOVE_LEFT), MP_ROM_INT(PY_LCD_TOUCH_GESTURE_MOVE_LEFT) }, { MP_ROM_QSTR(MP_QSTR_LCD_GESTURE_MOVE_LEFT), MP_ROM_INT(PY_LCD_TOUCH_GESTURE_MOVE_LEFT) },