summaryrefslogtreecommitdiffstats
path: root/app/oled1.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/oled1.c')
-rw-r--r--app/oled1.c127
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);
+}