remove software spi

This commit is contained in:
Shuanglei Tao
2025-04-19 17:04:02 +08:00
parent a52ad83b8c
commit 50a0f58725
6 changed files with 125 additions and 160 deletions

View File

@@ -34,7 +34,7 @@ void epd_config_read(epd_config_t *cfg)
fds_record_desc_t record_desc; fds_record_desc_t record_desc;
fds_find_token_t ftok; fds_find_token_t ftok;
memset(cfg, EPD_CONFIG_EMPTY, sizeof(epd_config_t)); memset(cfg, 0xFF, sizeof(epd_config_t));
memset(&ftok, 0x00, sizeof(fds_find_token_t)); memset(&ftok, 0x00, sizeof(fds_find_token_t));
if (fds_record_find(CONFIG_FILE_ID, CONFIG_REC_KEY, &record_desc, &ftok) != NRF_SUCCESS) { if (fds_record_find(CONFIG_FILE_ID, CONFIG_REC_KEY, &record_desc, &ftok) != NRF_SUCCESS) {
@@ -103,7 +103,7 @@ void epd_config_clear(epd_config_t *cfg)
bool epd_config_empty(epd_config_t *cfg) bool epd_config_empty(epd_config_t *cfg)
{ {
for (uint8_t i = 0; i < EPD_CONFIG_SIZE; i++) { for (uint8_t i = 0; i < EPD_CONFIG_SIZE; i++) {
if (((uint8_t *)cfg)[i] != EPD_CONFIG_EMPTY) if (((uint8_t *)cfg)[i] != 0xFF)
return false; return false;
} }
return true; return true;

View File

@@ -19,7 +19,6 @@ typedef struct
} epd_config_t; } epd_config_t;
#define EPD_CONFIG_SIZE (sizeof(epd_config_t) / sizeof(uint8_t)) #define EPD_CONFIG_SIZE (sizeof(epd_config_t) / sizeof(uint8_t))
#define EPD_CONFIG_EMPTY 0xFF
void epd_config_init(epd_config_t *cfg); void epd_config_init(epd_config_t *cfg);
void epd_config_read(epd_config_t *cfg); void epd_config_read(epd_config_t *cfg);

View File

@@ -32,11 +32,22 @@ static uint32_t EPD_BS_PIN = 13;
static uint32_t EPD_EN_PIN = 0xFF; static uint32_t EPD_EN_PIN = 0xFF;
static uint32_t EPD_LED_PIN = 0xFF; static uint32_t EPD_LED_PIN = 0xFF;
// EPD model #define SPI_INSTANCE 0 /**< SPI instance index. */
static epd_model_t *EPD = NULL; static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
#if defined(S112)
#define HAL_SPI_INSTANCE spi.u.spi.p_reg
#else
#define HAL_SPI_INSTANCE spi.p_registers
nrf_gpio_pin_dir_t nrf_gpio_pin_dir_get(uint32_t pin)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin);
return (nrf_gpio_pin_dir_t)((reg->PIN_CNF[pin] &
GPIO_PIN_CNF_DIR_Msk) >> GPIO_PIN_CNF_DIR_Pos);
}
#endif
// Arduino like function wrappers // Arduino like function wrappers
void pinMode(uint32_t pin, uint32_t mode) void pinMode(uint32_t pin, uint32_t mode)
{ {
switch (mode) switch (mode)
@@ -70,13 +81,7 @@ void digitalWrite(uint32_t pin, uint32_t value)
uint32_t digitalRead(uint32_t pin) uint32_t digitalRead(uint32_t pin)
{ {
#if defined(S112)
nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(pin); nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(pin);
#else
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin);
nrf_gpio_pin_dir_t dir = (nrf_gpio_pin_dir_t)((reg->PIN_CNF[pin] &
GPIO_PIN_CNF_DIR_Msk) >> GPIO_PIN_CNF_DIR_Pos);
#endif
if (dir == NRF_GPIO_PIN_DIR_INPUT) if (dir == NRF_GPIO_PIN_DIR_INPUT)
return nrf_gpio_pin_read(pin); return nrf_gpio_pin_read(pin);
else else
@@ -88,15 +93,15 @@ void delay(uint32_t ms)
nrf_delay_ms(ms); nrf_delay_ms(ms);
} }
// Hardware SPI (write only) void EPD_GPIO_Init(void)
#define SPI_INSTANCE 0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
static bool spi_initialized = false;
static void EPD_SPI_Init(void)
{ {
if (spi_initialized) return; pinMode(EPD_MOSI_PIN, OUTPUT);
pinMode(EPD_SCLK_PIN, OUTPUT);
pinMode(EPD_CS_PIN, OUTPUT);
pinMode(EPD_DC_PIN, OUTPUT);
pinMode(EPD_RST_PIN, OUTPUT);
pinMode(EPD_BUSY_PIN, INPUT);
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.sck_pin = EPD_SCLK_PIN; spi_config.sck_pin = EPD_SCLK_PIN;
spi_config.mosi_pin = EPD_MOSI_PIN; spi_config.mosi_pin = EPD_MOSI_PIN;
@@ -106,91 +111,82 @@ static void EPD_SPI_Init(void)
#else #else
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL)); APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL));
#endif #endif
spi_initialized = true;
if (EPD_EN_PIN != 0xFF) {
pinMode(EPD_EN_PIN, OUTPUT);
digitalWrite(EPD_EN_PIN, HIGH);
}
pinMode(EPD_BS_PIN, OUTPUT);
digitalWrite(EPD_BS_PIN, LOW);
digitalWrite(EPD_DC_PIN, LOW);
digitalWrite(EPD_CS_PIN, LOW);
digitalWrite(EPD_RST_PIN, HIGH);
if (EPD_LED_PIN != 0xFF)
pinMode(EPD_LED_PIN, OUTPUT);
} }
static void EPD_SPI_Uninit(void) void EPD_GPIO_Uninit(void)
{ {
if (!spi_initialized) return; EPD_LED_OFF();
nrf_drv_spi_uninit(&spi); nrf_drv_spi_uninit(&spi);
spi_initialized = false;
digitalWrite(EPD_DC_PIN, LOW);
digitalWrite(EPD_CS_PIN, LOW);
digitalWrite(EPD_RST_PIN, LOW);
if (EPD_EN_PIN != 0xFF) {
digitalWrite(EPD_EN_PIN, LOW);
}
// reset pin state
pinMode(EPD_MOSI_PIN, DEFAULT);
pinMode(EPD_SCLK_PIN, DEFAULT);
pinMode(EPD_CS_PIN, DEFAULT);
pinMode(EPD_DC_PIN, DEFAULT);
pinMode(EPD_RST_PIN, DEFAULT);
pinMode(EPD_BUSY_PIN, DEFAULT);
pinMode(EPD_BS_PIN, DEFAULT);
pinMode(EPD_EN_PIN, DEFAULT);
pinMode(EPD_LED_PIN, DEFAULT);
}
// SPI
void EPD_SPI_WriteBytes(uint8_t *value, uint8_t len)
{
nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(EPD_MOSI_PIN);
if (dir != NRF_GPIO_PIN_DIR_OUTPUT) {
pinMode(EPD_MOSI_PIN, OUTPUT);
nrf_spi_pins_set(HAL_SPI_INSTANCE, EPD_SCLK_PIN, EPD_MOSI_PIN, NRF_SPI_PIN_NOT_CONNECTED);
}
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, value, len, NULL, 0));
}
void EPD_SPI_ReadBytes(uint8_t *value, uint8_t len)
{
nrf_gpio_pin_dir_t dir = nrf_gpio_pin_dir_get(EPD_MOSI_PIN);
if (dir != NRF_GPIO_PIN_DIR_INPUT) {
pinMode(EPD_MOSI_PIN, INPUT);
nrf_spi_pins_set(HAL_SPI_INSTANCE, EPD_SCLK_PIN, NRF_SPI_PIN_NOT_CONNECTED, EPD_MOSI_PIN);
}
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, NULL, 0, value, len));
} }
void EPD_SPI_WriteByte(uint8_t value) void EPD_SPI_WriteByte(uint8_t value)
{ {
EPD_SPI_Init(); EPD_SPI_WriteBytes(&value, 1);
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &value, 1, NULL, 0));
} }
void EPD_SPI_WriteBytes(uint8_t *value, uint8_t len) uint8_t EPD_SPI_ReadByte(void)
{ {
EPD_SPI_Init(); uint8_t data;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, value, len, NULL, 0)); EPD_SPI_ReadBytes(&data, 1);
return data;
} }
// EPD
// Software SPI (read / write)
void EPD_SPI_WriteByte_SW(uint8_t data)
{
EPD_SPI_Uninit();
pinMode(EPD_MOSI_PIN, OUTPUT);
digitalWrite(EPD_CS_PIN, LOW);
for (int i = 0; i < 8; i++)
{
if ((data & 0x80) == 0) digitalWrite(EPD_MOSI_PIN, LOW);
else digitalWrite(EPD_MOSI_PIN, HIGH);
data <<= 1;
digitalWrite(EPD_SCLK_PIN, HIGH);
digitalWrite(EPD_SCLK_PIN, LOW);
}
digitalWrite(EPD_CS_PIN, HIGH);
}
uint8_t EPD_SPI_ReadByte_SW(void)
{
EPD_SPI_Uninit();
uint8_t j = 0xff;
pinMode(EPD_MOSI_PIN, INPUT);
digitalWrite(EPD_CS_PIN, LOW);
for (int i = 0; i < 8; i++)
{
j = j << 1;
if (digitalRead(EPD_MOSI_PIN)) j = j | 0x01;
else j = j & 0xfe;
digitalWrite(EPD_SCLK_PIN, HIGH);
digitalWrite(EPD_SCLK_PIN, LOW);
}
digitalWrite(EPD_CS_PIN, HIGH);
pinMode(EPD_MOSI_PIN, 1);
return j;
}
void EPD_WriteCommand_SW(uint8_t Reg)
{
digitalWrite(EPD_DC_PIN, LOW);
digitalWrite(EPD_CS_PIN, LOW);
EPD_SPI_WriteByte_SW(Reg);
digitalWrite(EPD_CS_PIN, HIGH);
}
void EPD_WriteByte_SW(uint8_t Data)
{
digitalWrite(EPD_DC_PIN, HIGH);
digitalWrite(EPD_CS_PIN, LOW);
EPD_SPI_WriteByte_SW(Data);
digitalWrite(EPD_CS_PIN, HIGH);
}
uint8_t EPD_ReadByte_SW(void)
{
digitalWrite(EPD_DC_PIN, HIGH);
return EPD_SPI_ReadByte_SW();
}
// Hardware SPI
void EPD_WriteCommand(uint8_t Reg) void EPD_WriteCommand(uint8_t Reg)
{ {
digitalWrite(EPD_DC_PIN, LOW); digitalWrite(EPD_DC_PIN, LOW);
@@ -209,6 +205,12 @@ void EPD_WriteData(uint8_t *Data, uint8_t Len)
EPD_SPI_WriteBytes(Data, Len); EPD_SPI_WriteBytes(Data, Len);
} }
uint8_t EPD_ReadByte(void)
{
digitalWrite(EPD_DC_PIN, HIGH);
return EPD_SPI_ReadByte();
}
void EPD_Reset(uint32_t value, uint16_t duration) void EPD_Reset(uint32_t value, uint16_t duration)
{ {
digitalWrite(EPD_RST_PIN, value); digitalWrite(EPD_RST_PIN, value);
@@ -257,54 +259,6 @@ void EPD_GPIO_Load(epd_config_t *cfg)
EPD_LED_PIN = cfg->led_pin; EPD_LED_PIN = cfg->led_pin;
} }
void EPD_GPIO_Init(void)
{
pinMode(EPD_CS_PIN, OUTPUT);
pinMode(EPD_DC_PIN, OUTPUT);
pinMode(EPD_RST_PIN, OUTPUT);
pinMode(EPD_BUSY_PIN, INPUT);
if (EPD_EN_PIN != 0xFF) {
pinMode(EPD_EN_PIN, OUTPUT);
digitalWrite(EPD_EN_PIN, HIGH);
}
pinMode(EPD_BS_PIN, OUTPUT);
digitalWrite(EPD_BS_PIN, LOW);
digitalWrite(EPD_DC_PIN, LOW);
digitalWrite(EPD_CS_PIN, LOW);
digitalWrite(EPD_RST_PIN, HIGH);
if (EPD_LED_PIN != 0xFF)
pinMode(EPD_LED_PIN, OUTPUT);
}
void EPD_GPIO_Uninit(void)
{
EPD_LED_OFF();
digitalWrite(EPD_DC_PIN, LOW);
digitalWrite(EPD_CS_PIN, LOW);
digitalWrite(EPD_RST_PIN, LOW);
if (EPD_EN_PIN != 0xFF) {
digitalWrite(EPD_EN_PIN, LOW);
}
EPD_SPI_Uninit();
// reset pin state
pinMode(EPD_MOSI_PIN, DEFAULT);
pinMode(EPD_SCLK_PIN, DEFAULT);
pinMode(EPD_CS_PIN, DEFAULT);
pinMode(EPD_DC_PIN, DEFAULT);
pinMode(EPD_RST_PIN, DEFAULT);
pinMode(EPD_BUSY_PIN, DEFAULT);
pinMode(EPD_BS_PIN, DEFAULT);
pinMode(EPD_EN_PIN, DEFAULT);
pinMode(EPD_LED_PIN, DEFAULT);
}
// lED // lED
void EPD_LED_ON(void) void EPD_LED_ON(void)
{ {
@@ -395,6 +349,9 @@ static epd_model_t *epd_models[] = {
&epd_uc8276_420_bwr, &epd_uc8276_420_bwr,
}; };
// EPD model
static epd_model_t *EPD = NULL;
epd_model_t *epd_get(void) epd_model_t *epd_get(void)
{ {
return EPD == NULL ? epd_models[0] : EPD; return EPD == NULL ? epd_models[0] : EPD;

View File

@@ -76,20 +76,17 @@ void EPD_GPIO_Load(epd_config_t *cfg);
void EPD_GPIO_Init(void); void EPD_GPIO_Init(void);
void EPD_GPIO_Uninit(void); void EPD_GPIO_Uninit(void);
// Software SPI (read / write) // SPI
void EPD_SPI_WriteByte_SW(uint8_t data);
uint8_t EPD_SPI_ReadByte_SW(void);
void EPD_WriteCommand_SW(uint8_t Reg);
void EPD_WriteByte_SW(uint8_t Data);
uint8_t EPD_ReadByte_SW(void);
// Hardware SPI (write only)
void EPD_SPI_WriteByte(uint8_t value);
void EPD_SPI_WriteBytes(uint8_t *value, uint8_t len); void EPD_SPI_WriteBytes(uint8_t *value, uint8_t len);
void EPD_SPI_ReadBytes(uint8_t *value, uint8_t len);
void EPD_SPI_WriteByte(uint8_t value);
uint8_t EPD_SPI_ReadByte(void);
// EPD
void EPD_WriteCommand(uint8_t Reg); void EPD_WriteCommand(uint8_t Reg);
void EPD_WriteByte(uint8_t Data); void EPD_WriteByte(uint8_t Data);
void EPD_WriteData(uint8_t *Data, uint8_t Len); void EPD_WriteData(uint8_t *Data, uint8_t Len);
uint8_t EPD_ReadByte(void);
void EPD_Reset(uint32_t value, uint16_t duration); void EPD_Reset(uint32_t value, uint16_t duration);
void EPD_WaitBusy(uint32_t value, uint16_t timeout); void EPD_WaitBusy(uint32_t value, uint16_t timeout);

View File

@@ -28,6 +28,11 @@
#define CMD_ANALOG_BLOCK_CTRL 0x74 // Set Analog Block Control #define CMD_ANALOG_BLOCK_CTRL 0x74 // Set Analog Block Control
#define CMD_DIGITAL_BLOCK_CTRL 0x7E // Set Digital Block Control #define CMD_DIGITAL_BLOCK_CTRL 0x7E // Set Digital Block Control
static void SSD1619_WaitBusy(uint16_t timeout)
{
EPD_WaitBusy(HIGH, timeout);
}
static void SSD1619_Update(uint8_t seq) static void SSD1619_Update(uint8_t seq)
{ {
EPD_WriteCommand(CMD_DISP_CTRL2); EPD_WriteCommand(CMD_DISP_CTRL2);
@@ -38,9 +43,9 @@ static void SSD1619_Update(uint8_t seq)
int8_t SSD1619_Read_Temp(void) int8_t SSD1619_Read_Temp(void)
{ {
SSD1619_Update(0xB1); SSD1619_Update(0xB1);
EPD_WaitBusy(HIGH, 500); SSD1619_WaitBusy(500);
EPD_WriteCommand_SW(CMD_TSENSOR_READ); EPD_WriteCommand(CMD_TSENSOR_READ);
return (int8_t) EPD_ReadByte_SW(); return (int8_t) EPD_ReadByte();
} }
void SSD1619_Force_Temp(int8_t value) void SSD1619_Force_Temp(int8_t value)
@@ -75,7 +80,7 @@ void SSD1619_Init()
EPD_Reset(HIGH, 10); EPD_Reset(HIGH, 10);
EPD_WriteCommand(CMD_SW_RESET); EPD_WriteCommand(CMD_SW_RESET);
EPD_WaitBusy(HIGH, 200); SSD1619_WaitBusy(200);
EPD_WriteCommand(CMD_ANALOG_BLOCK_CTRL); EPD_WriteCommand(CMD_ANALOG_BLOCK_CTRL);
EPD_WriteByte(0x54); EPD_WriteByte(0x54);
@@ -102,7 +107,7 @@ static void SSD1619_Refresh(void)
NRF_LOG_DEBUG("[EPD]: refresh begin\n"); NRF_LOG_DEBUG("[EPD]: refresh begin\n");
NRF_LOG_DEBUG("[EPD]: temperature: %d\n", SSD1619_Read_Temp()); NRF_LOG_DEBUG("[EPD]: temperature: %d\n", SSD1619_Read_Temp());
SSD1619_Update(0xF7); SSD1619_Update(0xF7);
EPD_WaitBusy(HIGH, 30000); SSD1619_WaitBusy(30000);
NRF_LOG_DEBUG("[EPD]: refresh end\n"); NRF_LOG_DEBUG("[EPD]: refresh end\n");
_setPartialRamArea(0, 0, EPD->width, EPD->height); // DO NOT REMOVE! _setPartialRamArea(0, 0, EPD->width, EPD->height); // DO NOT REMOVE!
@@ -139,6 +144,7 @@ void SSD1619_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y,
x -= x % 8; // byte boundary x -= x % 8; // byte boundary
w = wb * 8; // byte boundary w = wb * 8; // byte boundary
if (x + w > EPD->width || y + h > EPD->height) return; if (x + w > EPD->width || y + h > EPD->height) return;
_setPartialRamArea(x, y, w, h); _setPartialRamArea(x, y, w, h);
EPD_WriteCommand(CMD_WRITE_RAM1); EPD_WriteCommand(CMD_WRITE_RAM1);
for (uint16_t i = 0; i < h; i++) { for (uint16_t i = 0; i < h; i++) {

View File

@@ -56,23 +56,28 @@
#define PSR_SHD BIT(1) #define PSR_SHD BIT(1)
#define PSR_RST BIT(0) #define PSR_RST BIT(0)
static void UC8176_WaitBusy(uint16_t timeout)
{
EPD_WaitBusy(LOW, timeout);
}
static void UC8176_PowerOn(void) static void UC8176_PowerOn(void)
{ {
EPD_WriteCommand(CMD_PON); EPD_WriteCommand(CMD_PON);
EPD_WaitBusy(LOW, 100); UC8176_WaitBusy(100);
} }
static void UC8176_PowerOff(void) static void UC8176_PowerOff(void)
{ {
EPD_WriteCommand(CMD_POF); EPD_WriteCommand(CMD_POF);
EPD_WaitBusy(LOW, 100); UC8176_WaitBusy(100);
} }
// Read temperature from driver chip // Read temperature from driver chip
int8_t UC8176_Read_Temp(void) int8_t UC8176_Read_Temp(void)
{ {
EPD_WriteCommand_SW(CMD_TSC); EPD_WriteCommand(CMD_TSC);
return (int8_t) EPD_ReadByte_SW(); return (int8_t) EPD_ReadByte();
} }
// Force temperature (will trigger OTP LUT switch) // Force temperature (will trigger OTP LUT switch)
@@ -95,7 +100,7 @@ void UC8176_Refresh(void)
NRF_LOG_DEBUG("[EPD]: temperature: %d\n", UC8176_Read_Temp()); NRF_LOG_DEBUG("[EPD]: temperature: %d\n", UC8176_Read_Temp());
EPD_WriteCommand(CMD_DRF); EPD_WriteCommand(CMD_DRF);
delay(100); delay(100);
EPD_WaitBusy(LOW, 30000); UC8176_WaitBusy(30000);
UC8176_PowerOff(); UC8176_PowerOff();
NRF_LOG_DEBUG("[EPD]: refresh end\n"); NRF_LOG_DEBUG("[EPD]: refresh end\n");
} }
@@ -182,6 +187,7 @@ void UC8176_Write_Image(uint8_t *black, uint8_t *color, uint16_t x, uint16_t y,
x -= x % 8; // byte boundary x -= x % 8; // byte boundary
w = wb * 8; // byte boundary w = wb * 8; // byte boundary
if (x + w > EPD->width || y + h > EPD->height) return; if (x + w > EPD->width || y + h > EPD->height) return;
EPD_WriteCommand(CMD_PTIN); // partial in EPD_WriteCommand(CMD_PTIN); // partial in
_setPartialRamArea(x, y, w, h); _setPartialRamArea(x, y, w, h);
if (EPD->bwr) { if (EPD->bwr) {