diff options
Diffstat (limited to 'lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/I2C/main.c')
-rw-r--r-- | lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/I2C/main.c | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/I2C/main.c b/lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/I2C/main.c new file mode 100644 index 000000000..82c56d6b3 --- /dev/null +++ b/lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/I2C/main.c | |||
@@ -0,0 +1,239 @@ | |||
1 | |||
2 | /* | ||
3 | Copyright (C) 2020 Ein Terakawa | ||
4 | |||
5 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | you may not use this file except in compliance with the License. | ||
7 | You may obtain a copy of the License at | ||
8 | |||
9 | http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | |||
11 | Unless required by applicable law or agreed to in writing, software | ||
12 | distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | See the License for the specific language governing permissions and | ||
15 | limitations under the License. | ||
16 | */ | ||
17 | |||
18 | #include "hal.h" | ||
19 | #include "ssd1306.h" | ||
20 | |||
21 | static const uint8_t logo_bits[] = { | ||
22 | 0x00, 0x00, 0x00, 0x80, 0xF0, 0xF8, 0xFC, 0xFC, | ||
23 | 0xFE, 0x3E, 0x1E, 0x1E, 0x7E, 0x7C, 0x7C, 0x78, | ||
24 | 0x70, 0x40, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, | ||
25 | 0xFE, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x00, | ||
26 | 0x00, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0x00, | ||
27 | 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xC0, 0xE0, 0xE0, | ||
28 | 0xE0, 0xC0, 0x00, 0x00, 0xEE, 0xEE, 0xEE, 0xEE, | ||
29 | 0xEE, 0x00, 0x80, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, | ||
30 | 0x1E, 0x1E, 0x1E, 0xFE, 0xFC, 0xFC, 0xF8, 0xF0, | ||
31 | 0x80, 0x60, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xDE, | ||
32 | 0x9E, 0xBE, 0xBC, 0xBC, 0x38, 0x20, 0x00, 0x00, | ||
33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
38 | 0x00, 0x00, 0x00, 0x01, 0x0F, 0x1F, 0x3F, 0x3F, | ||
39 | 0x7F, 0x7C, 0x78, 0x78, 0x7E, 0x3E, 0x3E, 0x3E, | ||
40 | 0x0E, 0x02, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, | ||
41 | 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, | ||
42 | 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x00, | ||
43 | 0x7F, 0x7F, 0x7F, 0x7F, 0x1F, 0x79, 0x7F, 0x7F, | ||
44 | 0x7F, 0x3F, 0x0F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, | ||
45 | 0x7F, 0x00, 0x01, 0x0F, 0x1F, 0x3F, 0x3F, 0x7F, | ||
46 | 0x78, 0x78, 0x78, 0x7F, 0x3F, 0x3F, 0x1F, 0x0F, | ||
47 | 0x01, 0x04, 0x1C, 0x3D, 0x3D, 0x7D, 0x79, 0x7B, | ||
48 | 0x7B, 0x7F, 0x7F, 0x3F, 0x1F, 0x0C, 0x00, 0x00, | ||
49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
59 | 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, | ||
60 | 0xFE, 0xFE, 0xF8, 0xC0, 0xFE, 0xFE, 0xFE, 0xFE, | ||
61 | 0xFE, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, | ||
62 | 0xFE, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, | ||
63 | 0xFE, 0x00, 0x80, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, | ||
64 | 0x3E, 0x1E, 0x1E, 0x7E, 0x7C, 0x7C, 0x78, 0x70, | ||
65 | 0x40, 0x00, 0x38, 0x38, 0x38, 0xFE, 0xFE, 0xFE, | ||
66 | 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x20, 0x38, 0x3C, | ||
67 | 0x3C, 0x3E, 0x9E, 0x9E, 0xFE, 0xFE, 0xFC, 0xF8, | ||
68 | 0x70, 0x00, 0x20, 0x38, 0x3C, 0xFC, 0xFE, 0xDE, | ||
69 | 0xDE, 0xFE, 0xFE, 0x7C, 0x78, 0x20, 0x00, 0x00, | ||
70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
71 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
75 | 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, | ||
76 | 0x7F, 0x01, 0x07, 0x1F, 0x7F, 0x7F, 0x7F, 0x7F, | ||
77 | 0x7F, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x7F, | ||
78 | 0x7F, 0x7C, 0x7C, 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, | ||
79 | 0x03, 0x00, 0x01, 0x0F, 0x1F, 0x3F, 0x3F, 0x7F, | ||
80 | 0x7C, 0x78, 0x78, 0x7E, 0x3E, 0x3E, 0x3E, 0x0E, | ||
81 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, | ||
82 | 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x70, 0x7C, 0x7E, | ||
83 | 0x7F, 0x7F, 0x7F, 0x7F, 0x7B, 0x7B, 0x79, 0x79, | ||
84 | 0x78, 0x00, 0x04, 0x1C, 0x3C, 0x7D, 0x79, 0x79, | ||
85 | 0x79, 0x7F, 0x7F, 0x3F, 0x3F, 0x0E, 0x00, 0x00, | ||
86 | }; | ||
87 | |||
88 | static void draw_logo(SSD1306_DRIVER *ssd1306, bool invert, char xx) { | ||
89 | uint8_t width = ssd1306->width; | ||
90 | uint8_t height = ssd1306->height; | ||
91 | uint8_t num_pages = height / 8; | ||
92 | uint8_t invert_bits = invert ? 0xff : 0x00; | ||
93 | uint8_t *buf = SSD1306_GET_FRAMEBUFFER(ssd1306); | ||
94 | |||
95 | for (uint8_t row = 0; row < num_pages; ++row) { | ||
96 | for (uint8_t x = 0; x < width; ++x) { | ||
97 | uint8_t dat = logo_bits[(128 - xx + x) % 128 + (row % 4) * width]; | ||
98 | if (row / 2 % 2 == 0) { | ||
99 | dat ^= 0xff; | ||
100 | } | ||
101 | dat ^= invert_bits; /* Invert Imeage Bits */ | ||
102 | if (true) { | ||
103 | /* Horizontal Addressing Mode */ | ||
104 | buf[row * width + x] = dat; | ||
105 | } else { | ||
106 | /* Vertical Addressing Mode */ | ||
107 | buf[x * num_pages + row] = dat; | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | #define I2C_CLK_FREQ 1000000 | ||
114 | static const I2CConfig i2ccfg = { I2C_CLK_FREQ }; | ||
115 | #if NUC123_I2C_USE_I2C0 | ||
116 | DEFINE_SSD1306_DRIVER(ssd1306_128x64, &I2CD0, SSD1306_ADDRESS, 128, 64, false); | ||
117 | #endif | ||
118 | #if NUC123_I2C_USE_I2C1 | ||
119 | DEFINE_SSD1306_DRIVER(ssd1306_128x32, &I2CD1, SSD1306_ADDRESS, 128, 32, true); | ||
120 | #endif | ||
121 | |||
122 | #if I2C_USE_MUTUAL_EXCLUSION | ||
123 | #define ACQUIRE_BUS(oled_driver) i2cAcquireBus((oled_driver)->i2cd) | ||
124 | #define RELEASE_BUS(oled_driver) i2cReleaseBus((oled_driver)->i2cd) | ||
125 | #else | ||
126 | #define ACQUIRE_BUS(oled_driver) | ||
127 | #define RELEASE_BUS(oled_driver) | ||
128 | #endif | ||
129 | |||
130 | thread_reference_t thread1_ref = NULL; | ||
131 | |||
132 | static THD_WORKING_AREA(waThread1, 128); | ||
133 | static THD_FUNCTION(Thread1, arg) { | ||
134 | chRegSetThreadName("blinker"); | ||
135 | |||
136 | (void)arg; | ||
137 | while (true) { | ||
138 | if(osalThreadSuspendS(&thread1_ref) == MSG_OK) { | ||
139 | OnboardLED_On(); | ||
140 | }else{ | ||
141 | OnboardLED_Off(); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | #define I2C_THREAD_STACK_SIZE 256 | ||
147 | #if NUC123_I2C_USE_I2C0 | ||
148 | static THD_WORKING_AREA(waThread2, I2C_THREAD_STACK_SIZE); | ||
149 | static THD_FUNCTION(Thread2, arg) { | ||
150 | chRegSetThreadName("oled1"); | ||
151 | |||
152 | SSD1306_DRIVER *ssd1306 = (SSD1306_DRIVER *)arg; | ||
153 | ssd1306->i2ccfg = &i2ccfg; | ||
154 | ACQUIRE_BUS(ssd1306); | ||
155 | ssd1306_init(ssd1306); | ||
156 | RELEASE_BUS(ssd1306); | ||
157 | char x = 0; | ||
158 | while (true) { | ||
159 | osalThreadSleepMilliseconds(127); | ||
160 | bool invert = false; | ||
161 | draw_logo(ssd1306, invert, x); | ||
162 | ACQUIRE_BUS(ssd1306); | ||
163 | ssd1306_data(ssd1306); | ||
164 | /* RELEASE_BUS(ssd1306); */ | ||
165 | /* ACQUIRE_BUS(ssd1306); */ | ||
166 | if (x % 16 == 12) { | ||
167 | ssd1306_display_off(ssd1306); | ||
168 | } else if (x % 16 == 0) { | ||
169 | ssd1306_display_on(ssd1306); | ||
170 | } | ||
171 | RELEASE_BUS(ssd1306); | ||
172 | x = (x + 1) % 128; | ||
173 | } | ||
174 | } | ||
175 | #endif | ||
176 | |||
177 | #if NUC123_I2C_USE_I2C1 | ||
178 | static THD_WORKING_AREA(waThread3, I2C_THREAD_STACK_SIZE); | ||
179 | static THD_FUNCTION(Thread3, arg) { | ||
180 | chRegSetThreadName("oled2"); | ||
181 | |||
182 | SSD1306_DRIVER *ssd1306 = (SSD1306_DRIVER *)arg; | ||
183 | ssd1306->i2ccfg = &i2ccfg; | ||
184 | ACQUIRE_BUS(ssd1306); | ||
185 | #if true | ||
186 | /* Workaround for some 128x32 OLED modules typically with black PCB. */ | ||
187 | while (!ssd1306_init(ssd1306)) { | ||
188 | RELEASE_BUS(ssd1306); | ||
189 | osalThreadSleepMilliseconds(100); | ||
190 | ACQUIRE_BUS(ssd1306); | ||
191 | } | ||
192 | #endif | ||
193 | ssd1306_init(ssd1306); | ||
194 | RELEASE_BUS(ssd1306); | ||
195 | char x = 0; | ||
196 | while (true) { | ||
197 | osalThreadSleepMilliseconds(131); | ||
198 | bool invert = true; | ||
199 | draw_logo(ssd1306, invert, x); | ||
200 | ACQUIRE_BUS(ssd1306); | ||
201 | ssd1306_data(ssd1306); | ||
202 | RELEASE_BUS(ssd1306); | ||
203 | x = (x - 1) % 128; | ||
204 | } | ||
205 | } | ||
206 | #endif | ||
207 | |||
208 | /* | ||
209 | * Application entry point. | ||
210 | */ | ||
211 | int main(void) { | ||
212 | |||
213 | /* | ||
214 | * System initializations. | ||
215 | * - HAL initialization, this also initializes the configured device drivers | ||
216 | * and performs the board-specific initializations. | ||
217 | */ | ||
218 | halInit(); | ||
219 | |||
220 | /* | ||
221 | * chSysInit() will also enable interrupts. | ||
222 | */ | ||
223 | chSysInit(); | ||
224 | |||
225 | chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 2, Thread1, NULL); | ||
226 | #if NUC123_I2C_USE_I2C0 | ||
227 | chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO + 1, Thread2, &ssd1306_128x64); | ||
228 | #endif | ||
229 | #if NUC123_I2C_USE_I2C1 | ||
230 | chThdCreateStatic(waThread3, sizeof(waThread3), NORMALPRIO + 1, Thread3, &ssd1306_128x32); | ||
231 | #endif | ||
232 | |||
233 | while (true) { | ||
234 | osalThreadResumeS(&thread1_ref, MSG_OK); | ||
235 | osalThreadSleepMilliseconds(100); | ||
236 | osalThreadResumeS(&thread1_ref, MSG_RESET); | ||
237 | osalThreadSleepMilliseconds(400); | ||
238 | } | ||
239 | } | ||