#include "project.h" static uint8_t dma_buf[DMA_BUF_SZ]; uint8_t vram_1[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_1, DMA_BUF_SZ); if (ssd1306_cmds (I2C1, cmds, sizeof (cmds), 0)) { oled_sad++; return; } if (i2cp_start_transaction (I2C1, SSD1306_I2C_ADDRESS, I2C_WRITE)) { oled_sad++; return; } refresh_wdt = 0; dma_in_progress = 1; i2cp1_start_dma (dma_buf, DMA_BUF_SZ); } void dma1_channel6_isr (void) { if (dma_in_progress) { i2cp1_stop_dma(); i2cp_stop (I2C1); dma_in_progress = 0; } if (refresh_enabled) start_dma(); } void oled1_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 */ i2cp1_stop_dma(); i2cp_stop (I2C1); dma_in_progress = 0; if (oled_sad) { oled_sad = 0; i2cp1_reset_sm(); } start_dma(); } void oled1_enable_refresh (void) { refresh_enabled = 1; start_dma(); } void oled1_disable_refresh (void) { refresh_enabled = 0; while (dma_in_progress); } void oled1_init (void) { oled_reset (I2C1); delay_us (100); oled_generate_stream (vram_1); nvic_enable_irq (NVIC_DMA1_CHANNEL6_IRQ); oled1_enable_refresh(); } void oled1_shutdown (void) { oled1_disable_refresh(); oled_off (I2C1); }