diff options
Diffstat (limited to 'app/oled1.c')
-rw-r--r-- | app/oled1.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/app/oled1.c b/app/oled1.c new file mode 100644 index 0000000..48c6167 --- /dev/null +++ b/app/oled1.c @@ -0,0 +1,127 @@ +#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 < 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); +} |