167 lines
4.4 KiB
C
167 lines
4.4 KiB
C
#include "des_epd_impl.h"
|
|
|
|
_des_impl_t *_des_epd_impl_init(void) {
|
|
int spi_fd = open(CONFIG_SPIDEV_FILENAME, O_RDWR);
|
|
if(spi_fd < 0) return NULL;
|
|
|
|
uint32_t spi_mode = 0; // Nothing to be set in default mode.
|
|
|
|
int ret = ioctl(spi_fd, SPI_IOC_WR_MODE32, &spi_mode);
|
|
if(ret == -1) goto spi_err_out;
|
|
|
|
ret = ioctl(spi_fd, SPI_IOC_RD_MODE32, &spi_mode);
|
|
if(ret == -1) goto spi_err_out;
|
|
|
|
uint32_t spi_word_len = 8;
|
|
|
|
ret= ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_word_len);
|
|
if(ret == -1) goto spi_err_out;
|
|
|
|
ret = ioctl(spi_fd, SPI_IOC_RD_BITS_PER_WORD, &spi_word_len);
|
|
if(ret == -1) goto spi_err_out;
|
|
|
|
uint32_t spi_speed = 10000000; // 10MHz
|
|
|
|
ret = ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
|
|
if(ret == -1) goto spi_err_out;
|
|
|
|
ret = ioctl(spi_fd, SPI_IOC_RD_MAX_SPEED_HZ, &spi_speed);
|
|
if(ret == -1) goto spi_err_out;
|
|
|
|
_des_impl_t *impl = malloc(sizeof(_des_impl_t));
|
|
if(impl == NULL) goto spi_err_out;
|
|
|
|
impl->spi_fd = spi_fd;
|
|
|
|
impl->gpio_chip = gpiod_chip_open(CONFIG_GPIO_CHIP);
|
|
if(impl->gpio_chip == NULL) goto impl_err_out;
|
|
|
|
impl->gpio_line_res = gpiod_chip_get_line(impl->gpio_chip, CONFIG_RES_PIN);
|
|
if(impl->gpio_line_res == NULL) goto gpiod_err_out;
|
|
|
|
impl->gpio_line_dc = gpiod_chip_get_line(impl->gpio_chip, CONFIG_DC_PIN);
|
|
if(impl->gpio_line_dc == NULL) goto gpiod_err_out;
|
|
|
|
impl->gpio_line_busy = gpiod_chip_get_line(impl->gpio_chip, CONFIG_BUSY_PIN);
|
|
if(impl->gpio_line_busy == NULL) goto gpiod_err_out;
|
|
|
|
ret = gpiod_line_request_output(impl->gpio_line_dc, CONFIG_GPIO_CONSUMER, 1);
|
|
if(ret != 0) goto gpiod_err_out;
|
|
|
|
ret = gpiod_line_request_output(impl->gpio_line_res, CONFIG_GPIO_CONSUMER, 1);
|
|
if(ret != 0) goto gpiod_err_out;
|
|
|
|
ret = gpiod_line_request_input(impl->gpio_line_busy, CONFIG_GPIO_CONSUMER);
|
|
if(ret != 0) goto gpiod_err_out;
|
|
|
|
return impl;
|
|
|
|
gpiod_err_out:
|
|
gpiod_chip_close(impl->gpio_chip);
|
|
|
|
impl_err_out:
|
|
free(impl);
|
|
|
|
spi_err_out:
|
|
close(spi_fd);
|
|
return NULL;
|
|
}
|
|
|
|
int _des_epd_impl_deinit(_des_impl_t *handle) {
|
|
close(handle->spi_fd);
|
|
gpiod_chip_close(handle->gpio_chip);
|
|
free(handle);
|
|
return 0;
|
|
}
|
|
|
|
des_epd_ret_t _des_epd_write_cmd(void *handle, uint8_t *cmd, uint8_t len) {
|
|
_des_impl_t *impl = handle;
|
|
|
|
int ret = gpiod_line_set_value(impl->gpio_line_dc, 0);
|
|
if(ret) return DES_EPD_ERROR;
|
|
|
|
struct spi_ioc_transfer cmd_tr = {
|
|
.tx_buf = (unsigned long)cmd,
|
|
.rx_buf = (unsigned long)NULL,
|
|
.len = 1,
|
|
.bits_per_word = 8
|
|
};
|
|
|
|
ret = ioctl(impl->spi_fd, SPI_IOC_MESSAGE(1), &cmd_tr);
|
|
if(ret < 1) return DES_EPD_ERROR;
|
|
|
|
if(len > 1) {
|
|
ret = gpiod_line_set_value(impl->gpio_line_dc, 1); // Set DC pin
|
|
if(ret) return DES_EPD_ERROR;
|
|
cmd_tr.tx_buf = (unsigned long)&cmd[1]; //2nd transfer
|
|
cmd_tr.len = len - 1;
|
|
|
|
ret = ioctl(impl->spi_fd, SPI_IOC_MESSAGE(1), &cmd_tr);
|
|
if(ret < len - 1) return DES_EPD_ERROR;
|
|
}
|
|
|
|
return DES_EPD_OK;
|
|
}
|
|
|
|
des_epd_ret_t _des_epd_write_data(void *handle, uint8_t *data, uint16_t len) {
|
|
_des_impl_t *impl = handle;
|
|
|
|
int ret = gpiod_line_set_value(impl->gpio_line_dc, 1);
|
|
|
|
struct spi_ioc_transfer data_tr = {
|
|
.tx_buf = (unsigned long)data,
|
|
.rx_buf = (unsigned long)NULL,
|
|
.len = len,
|
|
.bits_per_word = 8
|
|
};
|
|
|
|
ret = ioctl(impl->spi_fd, SPI_IOC_MESSAGE(1), &data_tr);
|
|
if(ret < len) return DES_EPD_ERROR;
|
|
|
|
return DES_EPD_OK;
|
|
}
|
|
|
|
des_epd_ret_t _des_epd_reset(void *handle) {
|
|
_des_impl_t *impl = handle;
|
|
|
|
usleep(10 * 1000);
|
|
|
|
int ret = gpiod_line_set_value(impl->gpio_line_res, 0);
|
|
if(ret) return DES_EPD_ERROR;
|
|
|
|
usleep(10 * 1000);
|
|
|
|
ret = gpiod_line_set_value(impl->gpio_line_res, 1);
|
|
if(ret) return DES_EPD_ERROR;
|
|
|
|
usleep(10 * 1000);
|
|
|
|
ret = gpiod_line_set_value(impl->gpio_line_res, 0);
|
|
if(ret) return DES_EPD_ERROR;
|
|
|
|
usleep(10 * 1000);
|
|
|
|
ret = gpiod_line_set_value(impl->gpio_line_res, 1);
|
|
if(ret) return DES_EPD_ERROR;
|
|
|
|
usleep(10 * 1000);
|
|
|
|
return DES_EPD_OK;
|
|
}
|
|
|
|
des_epd_ret_t _des_epd_poll_busy(void *handle) {
|
|
_des_impl_t *impl = handle;
|
|
uint32_t i = 0;
|
|
usleep(1 * 1000);
|
|
while(i < CONFIG_MAX_POLLING_MSEC) {
|
|
int ret = gpiod_line_get_value(impl->gpio_line_busy);
|
|
if(ret != 1) {
|
|
i += 10;
|
|
usleep(10 * 1000);
|
|
}
|
|
else {
|
|
return DES_EPD_OK;
|
|
}
|
|
}
|
|
return DES_EPD_ERROR;
|
|
} |