generated from Embedded_Projects/Landzo_K60Z_LwIP
106 lines
3.0 KiB
C
106 lines
3.0 KiB
C
/* Drivers */
|
|
#include "fsl_clock.h"
|
|
#include "fsl_common.h"
|
|
#include "fsl_dmamux.h"
|
|
#include "fsl_edma.h"
|
|
#include "fsl_gpio.h"
|
|
|
|
/* Board */
|
|
#include "peripherals.h"
|
|
#include "pin_mux.h"
|
|
/* LCD panel */
|
|
#include "epd-spi/panel/lcd_generic_ssd1289.h"
|
|
|
|
/* Private header */
|
|
#include "lcd_impl.h"
|
|
|
|
#define IMPL_LCD_DMA_INSTANCE DMA0
|
|
#define IMPL_LCD_DMAMUX_INSTANCE DMAMUX0
|
|
#define IMPL_LCD_DMA_CHANNEL 0
|
|
#define IMPL_LCD_DMA_REQUEST 63 /* Always On Request */
|
|
|
|
#define IMPL_LCD_COMMAND_BASE ((uint16_t *)0x70000000)
|
|
#define IMPL_LCD_DATA_BASE ((uint16_t *)0x78000000)
|
|
|
|
static void epd_impl_edma_callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds) {
|
|
lcd_impl_t *impl = userData;
|
|
BaseType_t xHigherPriorityTaskWoken;
|
|
|
|
xSemaphoreGiveFromISR(impl->dma_semphr, &xHigherPriorityTaskWoken);
|
|
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
}
|
|
|
|
epd_ret_t epd_impl_init(void *handle) {
|
|
lcd_impl_t *impl = handle;
|
|
|
|
impl->dma_semphr = xSemaphoreCreateBinary();
|
|
if (impl->dma_semphr == NULL) {
|
|
return EPD_FAIL;
|
|
}
|
|
|
|
/* Async flush */
|
|
xSemaphoreGive(impl->dma_semphr);
|
|
|
|
DMAMUX_SetSource(IMPL_LCD_DMAMUX_INSTANCE, IMPL_LCD_DMA_CHANNEL, IMPL_LCD_DMA_REQUEST);
|
|
DMAMUX_EnableChannel(IMPL_LCD_DMAMUX_INSTANCE, IMPL_LCD_DMA_CHANNEL);
|
|
EDMA_CreateHandle(&impl->dma_handle, IMPL_LCD_DMA_INSTANCE, IMPL_LCD_DMA_CHANNEL);
|
|
EDMA_SetCallback(&impl->dma_handle, epd_impl_edma_callback, impl);
|
|
|
|
return EPD_OK;
|
|
}
|
|
|
|
epd_ret_t epd_impl_write_command(void *handle, uint8_t *command, uint32_t len) {
|
|
uint32_t param_len = (len - 1) / 2;
|
|
|
|
*IMPL_LCD_COMMAND_BASE = command[0];
|
|
|
|
for (uint32_t i = 0; i < param_len; i++) {
|
|
uint16_t le_param = (command[2 * i + 1] << 8) | command[2 * i + 2];
|
|
*IMPL_LCD_DATA_BASE = le_param;
|
|
}
|
|
|
|
return EPD_OK;
|
|
}
|
|
|
|
epd_ret_t epd_impl_write_data(void *handle, uint8_t *data, uint32_t len) {
|
|
lcd_impl_t *impl = handle;
|
|
|
|
uint32_t data_len = (len / 2);
|
|
|
|
edma_transfer_config_t cfg = {
|
|
.srcAddr = (uint32_t)data,
|
|
.srcTransferSize = kEDMA_TransferSize2Bytes,
|
|
.srcOffset = 2U,
|
|
.destAddr = (uint32_t)IMPL_LCD_DATA_BASE,
|
|
.destTransferSize = kEDMA_TransferSize2Bytes,
|
|
.destOffset = 0U, /* Destination is not self-incrementing */
|
|
.majorLoopCounts = data_len,
|
|
.minorLoopBytes = 2,
|
|
};
|
|
|
|
/* Wait for DMA transfer complete. */
|
|
if (xSemaphoreTake(impl->dma_semphr, portMAX_DELAY) != pdPASS) {
|
|
return EPD_FAIL;
|
|
}
|
|
|
|
EDMA_SubmitTransfer(&impl->dma_handle, &cfg);
|
|
EDMA_StartTransfer(&impl->dma_handle);
|
|
|
|
return EPD_OK;
|
|
}
|
|
|
|
epd_ret_t epd_impl_reset(void *handle) {
|
|
GPIO_WritePinOutput(BOARD_INITPINS_TFT_RESET_GPIO, BOARD_INITPINS_TFT_RESET_PIN, 0U);
|
|
vTaskDelay(pdMS_TO_TICKS(20));
|
|
GPIO_WritePinOutput(BOARD_INITPINS_TFT_RESET_GPIO, BOARD_INITPINS_TFT_RESET_PIN, 1U);
|
|
vTaskDelay(pdMS_TO_TICKS(20));
|
|
|
|
return EPD_OK;
|
|
}
|
|
|
|
epd_ret_t epd_impl_delay(void *handle, uint32_t msec) {
|
|
vTaskDelay(pdMS_TO_TICKS(msec));
|
|
|
|
return EPD_OK;
|
|
} |