Improvements and fixes
This commit is contained in:
parent
b6ac19a54d
commit
d27a2378b0
3 changed files with 126 additions and 11 deletions
|
|
@ -109,6 +109,46 @@ esp_err_t epd7in5_v3_init(epd7in5_v3_t *epd)
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t epd7in5_v3_init_fast(epd7in5_v3_t *epd)
|
||||||
|
{
|
||||||
|
spi_device_interface_config_t devcfg = {
|
||||||
|
.clock_speed_hz = 20 * 1000 * 1000, // 2 MHz
|
||||||
|
.mode = 0, // SPI mode 0
|
||||||
|
.spics_io_num = epd->pin_cs,
|
||||||
|
.queue_size = 1,
|
||||||
|
.flags = SPI_DEVICE_HALFDUPLEX // use .flags |= SPI_DEVICE_3WIRE if necessary
|
||||||
|
};
|
||||||
|
ESP_RETURN_ON_ERROR(spi_bus_add_device(epd->spi_host, &devcfg, &epd->spi), "add device", ret);
|
||||||
|
|
||||||
|
gpio_set_level(epd->pin_rst, 1);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
gpio_set_level(epd->pin_rst, 0);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(4));
|
||||||
|
gpio_set_level(epd->pin_rst, 1);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
|
||||||
|
epd7in5_v3_send_command(epd, 0x50);
|
||||||
|
epd7in5_v3_send_data(epd, 0x10);
|
||||||
|
epd7in5_v3_send_data(epd, 0x07);
|
||||||
|
|
||||||
|
epd7in5_v3_send_command(epd, 0x04);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
|
epd7in5_v3_busy_wait(epd);
|
||||||
|
|
||||||
|
epd7in5_v3_send_command(epd, 0x06);
|
||||||
|
epd7in5_v3_send_data(epd, 0x27);
|
||||||
|
epd7in5_v3_send_data(epd, 0x27);
|
||||||
|
epd7in5_v3_send_data(epd, 0x18);
|
||||||
|
epd7in5_v3_send_data(epd, 0x17);
|
||||||
|
|
||||||
|
epd7in5_v3_send_command(epd, 0xE0);
|
||||||
|
epd7in5_v3_send_data(epd, 0x02);
|
||||||
|
epd7in5_v3_send_command(epd, 0xE5);
|
||||||
|
epd7in5_v3_send_data(epd, 0x5A);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t epd7in5_v3_send_command(epd7in5_v3_t *epd, uint8_t cmd)
|
esp_err_t epd7in5_v3_send_command(epd7in5_v3_t *epd, uint8_t cmd)
|
||||||
{
|
{
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,13 @@ esp_err_t epd7in5_v3_create(epd7in5_v3_t *epd, spi_host_device_t host);
|
||||||
*/
|
*/
|
||||||
esp_err_t epd7in5_v3_init(epd7in5_v3_t *epd);
|
esp_err_t epd7in5_v3_init(epd7in5_v3_t *epd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the EPD panel with fast settings (no full refresh).
|
||||||
|
* @param epd Pointer to an epd7in5_v3_t struct (must be allocated by caller).
|
||||||
|
* @return ESP_OK on success, or an error code.
|
||||||
|
*/
|
||||||
|
esp_err_t epd7in5_v3_init_fast(epd7in5_v3_t *epd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a blocking command byte.
|
* @brief Send a blocking command byte.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
90
main/main.c
90
main/main.c
|
|
@ -52,22 +52,61 @@ QueueHandle_t timerEinkQueue;
|
||||||
QueueHandle_t timerAlarmQueue;
|
QueueHandle_t timerAlarmQueue;
|
||||||
QueueHandle_t alarmQueue;
|
QueueHandle_t alarmQueue;
|
||||||
|
|
||||||
|
void copybits(uint8_t *dest,
|
||||||
|
int dst_bit_offset,
|
||||||
|
const uint8_t *src,
|
||||||
|
int src_bit_offset,
|
||||||
|
int bit_length)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < bit_length; i++) {
|
||||||
|
// --- Read a single bit from src ---
|
||||||
|
int bit_idx_src = src_bit_offset + i;
|
||||||
|
int byte_idx_src = bit_idx_src / 8;
|
||||||
|
int bit_in_src = bit_idx_src % 8;
|
||||||
|
// extract MSB-first
|
||||||
|
uint8_t bit = (src[byte_idx_src] >> (7 - bit_in_src)) & 1;
|
||||||
|
|
||||||
|
// --- Write that bit into dest ---
|
||||||
|
int bit_idx_dst = dst_bit_offset + i;
|
||||||
|
int byte_idx_dst = bit_idx_dst / 8;
|
||||||
|
int bit_in_dst = bit_idx_dst % 8;
|
||||||
|
uint8_t mask = 1u << (7 - bit_in_dst);
|
||||||
|
|
||||||
|
// clear the destination bit and OR in our new bit
|
||||||
|
dest[byte_idx_dst] = (dest[byte_idx_dst] & ~mask)
|
||||||
|
| (bit << (7 - bit_in_dst));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void draw_char(uint8_t *image, int x, int y, char c) {
|
void draw_char(uint8_t *image, int x, int y, char c) {
|
||||||
uint32_t char_offset = (c - '0') * 16 * 176;
|
uint32_t char_offset = (c - '0') * 2816;
|
||||||
|
|
||||||
for(int i=0; i<176; ++i) {
|
for(int i=0; i<176; ++i) {
|
||||||
memcpy(&image[x + (y+i)*EPD_WIDTH/8], &OverpassMono_Bitmaps[i*16+char_offset], 16);
|
int length = 128;
|
||||||
|
int dst_offset = x;
|
||||||
|
int src_offset = 0;
|
||||||
|
|
||||||
|
if(dst_offset < 0) {
|
||||||
|
length += dst_offset;
|
||||||
|
src_offset = -dst_offset;
|
||||||
|
dst_offset = 0;
|
||||||
|
}
|
||||||
|
if(dst_offset + length > EPD_WIDTH) {
|
||||||
|
length = EPD_WIDTH - dst_offset;
|
||||||
|
}
|
||||||
|
if(length < 0) continue;
|
||||||
|
copybits(&image[(y+i)*EPD_WIDTH/8], dst_offset, &OverpassMono_Bitmaps[char_offset+i*16], src_offset, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_text(uint8_t *image, int x, int y, const char *text, int length)
|
void draw_text(uint8_t *image, int x, int y, const char *text, int length)
|
||||||
{
|
{
|
||||||
//89x130
|
|
||||||
for(int i=0; i<length; ++i) {
|
for(int i=0; i<length; ++i) {
|
||||||
if(text[i] < '0' || text[i] > '9') {
|
if(text[i] < '0' || text[i] > '9') {
|
||||||
ESP_LOGE(TAG, "Invalid character '%c' in text: %s", text[i], text);
|
ESP_LOGE(TAG, "Invalid character '%c' in text: %s", text[i], text);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
draw_char(image, x + i * 17, y, text[i]);
|
draw_char(image, x + i*136, y, text[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,22 +118,43 @@ void eink_task(void *pvParameter)
|
||||||
epd7in5_v3_t epd;
|
epd7in5_v3_t epd;
|
||||||
epd7in5_v3_create(&epd, SPI2_HOST);
|
epd7in5_v3_create(&epd, SPI2_HOST);
|
||||||
|
|
||||||
while(true) {
|
int x = 0;
|
||||||
|
int max_x = EPD_WIDTH - 536;
|
||||||
|
int y = 0;
|
||||||
|
int max_y = EPD_HEIGHT - 176;
|
||||||
|
|
||||||
// Wait for time update from timerQueue
|
int move_x = 10;
|
||||||
|
int move_y = 10;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
TimerEvent event;
|
TimerEvent event;
|
||||||
if (xQueueReceive(timerEinkQueue, &event, portMAX_DELAY) != pdTRUE) {
|
if (xQueueReceive(timerEinkQueue, &event, portMAX_DELAY) != pdTRUE) {
|
||||||
ESP_LOGE(TAG, "Failed to receive timer event from queue");
|
ESP_LOGE(TAG, "Failed to receive timer event from queue");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x += move_x;
|
||||||
|
y += move_y;
|
||||||
|
if (x <= 0 || x >= max_x - 1) {
|
||||||
|
move_x = -move_x;
|
||||||
|
x = (x < 0) ? 0 : max_x - 1;
|
||||||
|
}
|
||||||
|
if (y <= 0 || y >= max_y - 1) {
|
||||||
|
move_y = -move_y;
|
||||||
|
y = (y < 0) ? 0 : max_y - 1;
|
||||||
|
}
|
||||||
|
|
||||||
char buffer[5] = {0};
|
char buffer[5] = {0};
|
||||||
memcpy(buffer, &event.time, sizeof(event.time));
|
memcpy(buffer, &event.time, sizeof(event.time));
|
||||||
|
|
||||||
memset(image, 0x00, sizeof(image));
|
memset(image, 0x00, sizeof(image));
|
||||||
|
|
||||||
epd7in5_v3_init(&epd);
|
if (buffer[3] == '0') {
|
||||||
draw_text(image, 0, 0, buffer, 4);
|
epd7in5_v3_init(&epd);
|
||||||
|
} else {
|
||||||
|
epd7in5_v3_init_fast(&epd);
|
||||||
|
}
|
||||||
|
draw_text(image, x, y, buffer, 4);
|
||||||
epd7in5_v3_busy_wait(&epd);
|
epd7in5_v3_busy_wait(&epd);
|
||||||
epd7in5_v3_display(&epd, image);
|
epd7in5_v3_display(&epd, image);
|
||||||
epd7in5_v3_busy_wait(&epd);
|
epd7in5_v3_busy_wait(&epd);
|
||||||
|
|
@ -121,6 +181,8 @@ void radio_task(void *pvParameter)
|
||||||
{
|
{
|
||||||
bool radioActive = false;
|
bool radioActive = false;
|
||||||
|
|
||||||
|
int volume = 25;
|
||||||
|
|
||||||
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER);
|
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER);
|
||||||
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL));
|
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL));
|
||||||
|
|
||||||
|
|
@ -171,6 +233,12 @@ void radio_task(void *pvParameter)
|
||||||
AlarmEvent event;
|
AlarmEvent event;
|
||||||
while(true) {
|
while(true) {
|
||||||
if(!radioActive) {
|
if(!radioActive) {
|
||||||
|
//write 0
|
||||||
|
memset(samples, 0, BUFFER_SAMPLES * sizeof(int16_t));
|
||||||
|
size_t bytes_to_write = BUFFER_SAMPLES * sizeof(int16_t);
|
||||||
|
size_t bytes_written = 0;
|
||||||
|
ESP_ERROR_CHECK(i2s_channel_write(tx_handle, samples, bytes_to_write, &bytes_written, portMAX_DELAY));
|
||||||
|
|
||||||
if(xQueueReceive(alarmQueue, &event, portMAX_DELAY) && event.event_id == 1) {
|
if(xQueueReceive(alarmQueue, &event, portMAX_DELAY) && event.event_id == 1) {
|
||||||
ESP_LOGI(TAG, "Alarm activated, starting radio");
|
ESP_LOGI(TAG, "Alarm activated, starting radio");
|
||||||
radioActive = true;
|
radioActive = true;
|
||||||
|
|
@ -184,7 +252,7 @@ void radio_task(void *pvParameter)
|
||||||
//Do radio shit
|
//Do radio shit
|
||||||
for (int i = 0; i < BUFFER_SAMPLES; ++i) {
|
for (int i = 0; i < BUFFER_SAMPLES; ++i) {
|
||||||
int16_t sample = level_up[(i+offset) % level_up_size];
|
int16_t sample = level_up[(i+offset) % level_up_size];
|
||||||
samples[i] = sample / 4;
|
samples[i] = (uint16_t)(((uint32_t)sample) * volume / 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bytes_to_write = BUFFER_SAMPLES * sizeof(int16_t);
|
size_t bytes_to_write = BUFFER_SAMPLES * sizeof(int16_t);
|
||||||
|
|
@ -203,8 +271,8 @@ void alarm_task(void *pvParameter)
|
||||||
{
|
{
|
||||||
bool alarmActive = false;
|
bool alarmActive = false;
|
||||||
|
|
||||||
int alarmStart = 830; // 20:55 in HHMM format
|
int alarmStart = 830;
|
||||||
int alarmEnd = 900; // 20:56 in HHMM format
|
int alarmEnd = 900;
|
||||||
|
|
||||||
TimerEvent event;
|
TimerEvent event;
|
||||||
while(true) {
|
while(true) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue