diff --git a/src/databus/Arduino_ESP32LCD8.cpp b/src/databus/Arduino_ESP32LCD8.cpp index fe2f3e8a..febf1209 100644 --- a/src/databus/Arduino_ESP32LCD8.cpp +++ b/src/databus/Arduino_ESP32LCD8.cpp @@ -431,6 +431,87 @@ void Arduino_ESP32LCD8::writeRepeat(uint16_t p, uint32_t len) */ void Arduino_ESP32LCD8::writePixels(uint16_t *data, uint32_t len) { + uint32_t xferLen, l; + + if (esp_ptr_dma_capable(data)) + { + while (len > (USE_DMA_THRESHOLD)) // While pixels remain + { + xferLen = (len >= LCD_MAX_PIXELS_AT_ONCE) ? (LCD_MAX_PIXELS_AT_ONCE) : len; // How many this pass? + + _data16.value = *data++; + _data32.value = 0; + _data32.lsb = _data16.msb; + _data32.lsb_2 = _data16.lsb; + + LCD_CAM.lcd_cmd_val.val = _data32.value; + WAIT_LCD_NOT_BUSY; + LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; + + _data16.value = *data++; + _data32.value = 0; + _data32.lsb = _data16.msb; + _data32.lsb_2 = _data16.lsb; + + l = xferLen - 2; + l <<= 1; + *(uint32_t *)_dmadesc = ((l + 3) & (~3)) | l << 12 | 0xC0000000; + _dmadesc->buffer = data; + _dmadesc->next = nullptr; + gdma_start(_dma_chan, (intptr_t)(_dmadesc)); + LCD_CAM.lcd_cmd_val.val = _data32.value; + LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_UPDATE_REG; + + data += xferLen - 2; + len -= xferLen; + + WAIT_LCD_NOT_BUSY; + LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_START; + } + } + else + { + while (len > (USE_DMA_THRESHOLD)) // While pixels remain + { + xferLen = (len >= LCD_MAX_PIXELS_AT_ONCE) ? (LCD_MAX_PIXELS_AT_ONCE) : len; // How many this pass? + + _data16.value = *data++; + _data32.value = 0; + _data32.lsb = _data16.msb; + _data32.lsb_2 = _data16.lsb; + + LCD_CAM.lcd_cmd_val.val = _data32.value; + WAIT_LCD_NOT_BUSY; + LCD_CAM.lcd_user.val = LCD_CAM_LCD_CMD | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_UPDATE_REG | LCD_CAM_LCD_START; + + _data16.value = *data++; + _data32.value = 0; + _data32.lsb = _data16.msb; + _data32.lsb_2 = _data16.lsb; + + l = xferLen - 2; + l <<= 1; + for (uint32_t i = 0; i < l;) + { + _data16.value = *data++; + _buffer[i++] = _data16.msb; + _buffer[i++] = _data16.lsb; + } + + *(uint32_t *)_dmadesc = ((l + 3) & (~3)) | l << 12 | 0xC0000000; + _dmadesc->buffer = _buffer32; + _dmadesc->next = nullptr; + gdma_start(_dma_chan, (intptr_t)(_dmadesc)); + LCD_CAM.lcd_cmd_val.val = _data32.value; + LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_UPDATE_REG; + + len -= xferLen; + + WAIT_LCD_NOT_BUSY; + LCD_CAM.lcd_user.val = LCD_CAM_LCD_ALWAYS_OUT_EN | LCD_CAM_LCD_DOUT | LCD_CAM_LCD_CMD | LCD_CAM_LCD_CMD_2_CYCLE_EN | LCD_CAM_LCD_START; + } + } + while (len--) { _data16.value = *data++; @@ -451,7 +532,7 @@ void Arduino_ESP32LCD8::writePixels(uint16_t *data, uint32_t len) */ void Arduino_ESP32LCD8::writeBytes(uint8_t *data, uint32_t len) { - uint32_t xferLen, l, m; + uint32_t xferLen, l; if (esp_ptr_dma_capable(data)) {