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;
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
|
|
|||
88
main/main.c
88
main/main.c
|
|
@ -52,22 +52,61 @@ QueueHandle_t timerEinkQueue;
|
|||
QueueHandle_t timerAlarmQueue;
|
||||
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) {
|
||||
uint32_t char_offset = (c - '0') * 16 * 176;
|
||||
uint32_t char_offset = (c - '0') * 2816;
|
||||
|
||||
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)
|
||||
{
|
||||
//89x130
|
||||
for(int i=0; i<length; ++i) {
|
||||
if(text[i] < '0' || text[i] > '9') {
|
||||
ESP_LOGE(TAG, "Invalid character '%c' in text: %s", text[i], text);
|
||||
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_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;
|
||||
if (xQueueReceive(timerEinkQueue, &event, portMAX_DELAY) != pdTRUE) {
|
||||
ESP_LOGE(TAG, "Failed to receive timer event from queue");
|
||||
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};
|
||||
memcpy(buffer, &event.time, sizeof(event.time));
|
||||
|
||||
memset(image, 0x00, sizeof(image));
|
||||
|
||||
if (buffer[3] == '0') {
|
||||
epd7in5_v3_init(&epd);
|
||||
draw_text(image, 0, 0, buffer, 4);
|
||||
} else {
|
||||
epd7in5_v3_init_fast(&epd);
|
||||
}
|
||||
draw_text(image, x, y, buffer, 4);
|
||||
epd7in5_v3_busy_wait(&epd);
|
||||
epd7in5_v3_display(&epd, image);
|
||||
epd7in5_v3_busy_wait(&epd);
|
||||
|
|
@ -121,6 +181,8 @@ void radio_task(void *pvParameter)
|
|||
{
|
||||
bool radioActive = false;
|
||||
|
||||
int volume = 25;
|
||||
|
||||
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));
|
||||
|
||||
|
|
@ -171,6 +233,12 @@ void radio_task(void *pvParameter)
|
|||
AlarmEvent event;
|
||||
while(true) {
|
||||
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) {
|
||||
ESP_LOGI(TAG, "Alarm activated, starting radio");
|
||||
radioActive = true;
|
||||
|
|
@ -184,7 +252,7 @@ void radio_task(void *pvParameter)
|
|||
//Do radio shit
|
||||
for (int i = 0; i < BUFFER_SAMPLES; ++i) {
|
||||
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);
|
||||
|
|
@ -203,8 +271,8 @@ void alarm_task(void *pvParameter)
|
|||
{
|
||||
bool alarmActive = false;
|
||||
|
||||
int alarmStart = 830; // 20:55 in HHMM format
|
||||
int alarmEnd = 900; // 20:56 in HHMM format
|
||||
int alarmStart = 830;
|
||||
int alarmEnd = 900;
|
||||
|
||||
TimerEvent event;
|
||||
while(true) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue