1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#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);
}
|