#include "project.h" static uint8_t dma_buf[DMA_BUF_SZ]; uint8_t vram_2[DMA_BUF_SZ]; static int dma_in_progress = 0; static int refresh_enabled = 0; static uint32_t refresh_wdt = 0; static int oled_sad = 0; static void start_dma (void) { uint8_t cmds[] = { SSD1306_SET_PAGE_ADDR, 0, 0xff, SSD1306_SET_COLUMN_ADDR, 0, SSD1306_WIDTH - 1 }; if (dma_in_progress) return; memcpy (dma_buf, vram_2, DMA_BUF_SZ); if (ssd1306_cmds (I2C2, cmds, sizeof (cmds), 0)) { oled_sad++; return; } if (i2cp_start_transaction (I2C2, SSD1306_I2C_ADDRESS, I2C_WRITE)) { oled_sad++; return; } refresh_wdt = 0; dma_in_progress = 1; i2cp2_start_dma (dma_buf, DMA_BUF_SZ); } void dma1_channel4_isr (void) { if (dma_in_progress) { i2cp2_stop_dma(); i2cp_stop (I2C2); dma_in_progress = 0; } if (refresh_enabled) start_dma(); } void oled2_ticker (void) { if (!refresh_enabled) return; refresh_wdt++; if ((refresh_wdt < MS_TO_TICKS (1000)) && (!oled_sad)) return; refresh_wdt = 0; /*No refresh for 1s, restart everything */ i2cp2_stop_dma(); i2cp_stop (I2C2); dma_in_progress = 0; if (oled_sad) { oled_sad = 0; i2cp2_reset_sm(); } start_dma(); } void oled2_enable_refresh (void) { refresh_enabled = 1; start_dma(); } void oled2_disable_refresh (void) { refresh_enabled = 0; while (dma_in_progress); } void oled2_init (void) { oled_reset (I2C2); delay_us (100); oled_generate_stream (vram_2); nvic_enable_irq (NVIC_DMA1_CHANNEL4_IRQ); oled2_enable_refresh(); } void oled2_shutdown (void) { oled2_disable_refresh(); oled_off (I2C2); }