153 lines
4.1 KiB
C
153 lines
4.1 KiB
C
#include <string.h>
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
|
|
#include "user_board.h"
|
|
|
|
#include "app_lib_epd_impl.h"
|
|
|
|
#define MAXIMUM_XFER_SIZE 4000
|
|
#define MAX_BUSY_POLL_COUNT 10
|
|
|
|
static void _spi_pre_transfere_callback(spi_transaction_t *txn) {
|
|
gpio_set_level(BOARD_EPD_DC_PIN, (int)txn->user);
|
|
}
|
|
|
|
void app_lib_epd_impl_init(app_lib_epd_impl_t *impl) {
|
|
gpio_config_t io_config = {
|
|
.intr_type = GPIO_INTR_DISABLE,
|
|
.mode = GPIO_MODE_OUTPUT_OD,
|
|
.pin_bit_mask = (1 << BOARD_EPD_RES_PIN),
|
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
|
.pull_down_en = GPIO_PULLDOWN_DISABLE
|
|
};
|
|
gpio_config(&io_config);
|
|
|
|
io_config.pin_bit_mask = (1 << BOARD_EPD_DC_PIN);
|
|
io_config.pull_up_en = GPIO_PULLUP_DISABLE;
|
|
io_config.mode = GPIO_MODE_OUTPUT;
|
|
gpio_config(&io_config);
|
|
|
|
io_config.pin_bit_mask = (1 << BOARD_EPD_BUSY_PIN);
|
|
io_config.mode = GPIO_MODE_INPUT;
|
|
gpio_config(&io_config);
|
|
|
|
spi_bus_config_t bus_cfg = {
|
|
.mosi_io_num = BOARD_EPD_SPI_MOSI_PIN,
|
|
.sclk_io_num = BOARD_EPD_SPI_SCK_PIN,
|
|
.miso_io_num = -1,
|
|
.quadhd_io_num = -1,
|
|
.quadwp_io_num = -1,
|
|
.max_transfer_sz = MAXIMUM_XFER_SIZE
|
|
};
|
|
|
|
spi_device_interface_config_t interface_config = {
|
|
.clock_speed_hz = 16 * 1000 * 1000,
|
|
.mode = 0,
|
|
.spics_io_num = BOARD_EPD_SPI_CS_PIN,
|
|
.queue_size = 7,
|
|
.pre_cb = _spi_pre_transfere_callback,
|
|
.flags = SPI_DEVICE_HALFDUPLEX,
|
|
};
|
|
|
|
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &bus_cfg, SPI_DMA_CH_AUTO));
|
|
ESP_ERROR_CHECK(spi_bus_add_device(SPI2_HOST, &interface_config, &impl->spi_handle));
|
|
}
|
|
|
|
gd_epd_042_ret_t app_lib_epd_impl_reset(app_lib_epd_impl_t *impl) {
|
|
gpio_set_level(BOARD_EPD_RES_PIN, 1);
|
|
vTaskDelay(10);
|
|
gpio_set_level(BOARD_EPD_RES_PIN, 0);
|
|
vTaskDelay(10);
|
|
gpio_set_level(BOARD_EPD_RES_PIN, 1);
|
|
vTaskDelay(10);
|
|
gpio_set_level(BOARD_EPD_RES_PIN, 0);
|
|
vTaskDelay(10);
|
|
gpio_set_level(BOARD_EPD_RES_PIN, 1);
|
|
vTaskDelay(10);
|
|
gpio_set_level(BOARD_EPD_RES_PIN, 0);
|
|
vTaskDelay(10);
|
|
gpio_set_level(BOARD_EPD_RES_PIN, 1);
|
|
vTaskDelay(10);
|
|
|
|
return EPD_OK;
|
|
}
|
|
|
|
gd_epd_042_ret_t app_lib_epd_delay_ms(app_lib_epd_impl_t *impl, uint32_t ms) {
|
|
vTaskDelay(pdMS_TO_TICKS(ms));
|
|
|
|
return EPD_OK;
|
|
}
|
|
|
|
gd_epd_042_ret_t app_lib_epd_impl_write_cmd(app_lib_epd_impl_t *impl, uint8_t *cmd, uint8_t len) {
|
|
esp_err_t ret;
|
|
spi_transaction_t txn = {
|
|
.length = 8,
|
|
.tx_buffer = cmd,
|
|
.user = (void *)0
|
|
};
|
|
|
|
ret = spi_device_polling_transmit(impl->spi_handle, &txn);
|
|
if(ret != ESP_OK) return EPD_ERR;
|
|
|
|
if(len > 1) {
|
|
txn.length = 8 * (len - 1);
|
|
txn.tx_buffer = &cmd[1];
|
|
txn.user = (void *)1;
|
|
|
|
ret = spi_device_polling_transmit(impl->spi_handle, &txn);
|
|
if(ret != ESP_OK) return EPD_ERR;
|
|
}
|
|
|
|
return EPD_OK;
|
|
}
|
|
|
|
gd_epd_042_ret_t app_lib_epd_impl_write_data(app_lib_epd_impl_t *impl, uint8_t *data, uint32_t len) {
|
|
esp_err_t ret;
|
|
|
|
uint8_t *dma_buffer = heap_caps_malloc(MAXIMUM_XFER_SIZE, MALLOC_CAP_DMA);
|
|
if(dma_buffer == NULL) return EPD_ERR;
|
|
|
|
uint8_t has_partial = (len % MAXIMUM_XFER_SIZE ? 1 : 0);
|
|
uint32_t txn_count = len / MAXIMUM_XFER_SIZE + has_partial;
|
|
|
|
spi_transaction_t txn = {
|
|
.length = 8 * len,
|
|
.tx_buffer = data,
|
|
.user = (void *)1
|
|
};
|
|
|
|
for(uint32_t i = 0; i < txn_count; i++) {
|
|
uint16_t txn_bytes = MAXIMUM_XFER_SIZE;
|
|
if(i == (txn_count - 1) && has_partial) {
|
|
txn_bytes = len % MAXIMUM_XFER_SIZE;
|
|
}
|
|
|
|
memcpy(dma_buffer, &data[i * MAXIMUM_XFER_SIZE], txn_bytes);
|
|
|
|
txn.length = 8 * txn_bytes;
|
|
txn.tx_buffer = dma_buffer;
|
|
|
|
ret = spi_device_polling_transmit(impl->spi_handle, &txn);
|
|
if(ret != ESP_OK) return EPD_ERR;
|
|
}
|
|
|
|
free(dma_buffer);
|
|
|
|
return EPD_OK;
|
|
}
|
|
|
|
gd_epd_042_ret_t app_lib_epd_impl_poll_busy(app_lib_epd_impl_t *impl) {
|
|
uint8_t count = MAX_BUSY_POLL_COUNT;
|
|
while(gpio_get_level(BOARD_EPD_BUSY_PIN) == 0) {
|
|
vTaskDelay(10);
|
|
if(count == 0) {
|
|
return EPD_ERR;
|
|
}
|
|
count--;
|
|
}
|
|
|
|
return EPD_OK;
|
|
|
|
} |