Browse code

Add source code of the firmware for the IO Board

Pawel Jablonski authored on 05/06/2023 17:01:27
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,317 @@
1
+/*
2
+ * Author: Pawel Jablonski
3
+ * E-mail: pj@xirx.net
4
+ * WWW: xirx.net
5
+ * GIT: git.xirx.net
6
+ *
7
+ * License: You can use this code however you like
8
+ * but leave information about the original author.
9
+ * Code is free for non-commercial and commercial use.
10
+ */
11
+
12
+#include <stm32f0xx.h>
13
+#include <stm32f0xx_hal.h>
14
+#include <stm32f0xx_hal_gpio.h>
15
+#include <stm32f0xx_hal_rcc.h>
16
+#include <system_stm32f0xx.h>
17
+
18
+#include "type.h"
19
+#include "led.h"
20
+
21
+#include "keyboard.h"
22
+
23
+#define KEYBOARD_COLUMN_QUANTITY 15 //!< Quantity of key columns of keyboard
24
+#define KEYBOARD_ROW_QUANTITY 5 //!< Quantity of key rows of keyboard
25
+
26
+#define KEYBOARD_STATUS_RETRY 5 //!< How many times read status of all keys
27
+#define KEYBOARD_STATUS_MIN 4 //!< How many statuses must be high to count a key as clicked
28
+
29
+#define KEYBOARD_BUFFER_SIZE 16 //!< Global input buffer size
30
+#define KEYBOARD_LOCAL_BUFFER_SIZE 8 //!< Local input buffer size for the read function
31
+
32
+#define KEYBOARD_KEY_ESC 0x1b //!< Escape key code
33
+#define KEYBOARD_KEY_BACKSPACE 0x08 //!< Backspace key code
34
+#define KEYBOARD_KEY_TAB 0x09 //!< Tab key code
35
+#define KEYBOARD_KEY_ENTER 0x0d //!< Enter key code
36
+#define KEYBOARD_KEY_DELETE 0x7f //!< Delete key code
37
+#define KEYBOARD_KEY_UP 0x11 //!< Up arrow key code
38
+#define KEYBOARD_KEY_DOWN 0x12 //!< Down arrow key code
39
+#define KEYBOARD_KEY_LEFT 0x13 //!< Left arrow key code
40
+#define KEYBOARD_KEY_RIGHT 0x14 //!< Right arrow key code
41
+
42
+#define KEYBOARD_CTRL_MASK 0x80 //!< Mask used to check if the control key is pressed too
43
+#define KEYBOARD_CTRL_MIN_CODE 0x20 //!< Minimum key code where the control mask can be set
44
+
45
+#define KEYBOARD_POS_SHIFT_LEFT_COLUMN 14 //!< Left shift key column position in the key statuses matrix
46
+#define KEYBOARD_POS_SHIFT_LEFT_ROW 1 //!< Left shift key row position in the key statuses matrix
47
+#define KEYBOARD_POS_SHIFT_RIGHT_COLUMN 3 //!< Right shift key column position in the key statuses matrix
48
+#define KEYBOARD_POS_SHIFT_RIGHT_ROW 1 //!< Right shift key row position in the key statuses matrix
49
+#define KEYBOARD_POS_CAPSLOCK_COLUMN 14 //!< Capslock key column position in the key statuses matrix
50
+#define KEYBOARD_POS_CAPSLOCK_ROW 2 //!< Capslock key row position in the key statuses matrix
51
+#define KEYBOARD_POS_CTRL_COLUMN 14 //!< Control key column position in the key statuses matrix
52
+#define KEYBOARD_POS_CTRL_ROW 0 //!< Control key row position in the key statuses matrix
53
+
54
+//! Keyboard matrix with data for every key for down and upper case
55
+static const unsigned char keyCode[2][KEYBOARD_ROW_QUANTITY][KEYBOARD_COLUMN_QUANTITY] = {
56
+	{
57
+		{ 0x00, KEYBOARD_KEY_RIGHT, KEYBOARD_KEY_DOWN, KEYBOARD_KEY_LEFT, 0x00, 0x00, 0x00, 0x00, 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0xff },
58
+		{ 0x00, KEYBOARD_KEY_DELETE, KEYBOARD_KEY_UP, 0xff, '/', '.', ',', 'm', 'n', 'b', 'v', 'c', 'x', 'z', 0xff },
59
+		{ 0x00, KEYBOARD_KEY_ENTER, 0x00, '\'', ';', 'l', 'k', 'j', 'h', 'g', 'f', 'd', 's', 'a', 0xff },
60
+		{ 0x00, '\\', ']', '[', 'p', 'o', 'i', 'u', 'y', 't', 'r', 'e', 'w', 'q', KEYBOARD_KEY_TAB },
61
+		{ KEYBOARD_KEY_BACKSPACE, '`', '+', '-', '0', '9', '8', '7', '6', '5', '4', '3', '2', '1', KEYBOARD_KEY_ESC }
62
+	},
63
+	{
64
+		{ 0x00, KEYBOARD_KEY_RIGHT, KEYBOARD_KEY_DOWN, KEYBOARD_KEY_LEFT, 0x00, 0x00, 0x00, 0x00, 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0xff },
65
+		{ 0x00, KEYBOARD_KEY_DELETE, KEYBOARD_KEY_UP, 0xff, '?', '>', '<', 'M', 'N', 'B', 'V', 'C', 'X', 'Z', 0xff },
66
+		{ 0x00, KEYBOARD_KEY_ENTER, 0x00, '"', ':', 'L', 'K', 'J', 'H', 'G', 'F', 'D', 'S', 'A', 0xff },
67
+		{ 0x00, '|', '}', '{', 'P', 'O', 'I', 'U', 'Y', 'T', 'R', 'E', 'W', 'Q', KEYBOARD_KEY_TAB },
68
+		{ KEYBOARD_KEY_BACKSPACE, '~', '+', '_', ')', '(', '*', '&', '^', '%', '$', '#', '@', '!', KEYBOARD_KEY_ESC },
69
+	}
70
+};
71
+
72
+static bool keyLastStatus[KEYBOARD_ROW_QUANTITY][KEYBOARD_COLUMN_QUANTITY]; //!< Last key statuses matrix
73
+static bool capslock = 0; //!< Capslock key status
74
+
75
+static unsigned char buffer[KEYBOARD_BUFFER_SIZE]; //!< Circular keyboard input buffer
76
+static volatile unsigned int bufferStart = 0; //!< Data start position
77
+static volatile unsigned int bufferEnd = 0; //!< Data end position
78
+
79
+//! Init keyboard and set up the pin outs and inputs
80
+void keyboardInit(void)
81
+{
82
+	GPIO_InitTypeDef gpioInit = {0};
83
+	
84
+	__HAL_RCC_GPIOC_CLK_ENABLE();
85
+	
86
+	gpioInit.Pin = (GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
87
+	gpioInit.Mode = GPIO_MODE_OUTPUT_PP;
88
+	gpioInit.Pull = GPIO_NOPULL;
89
+	gpioInit.Speed = GPIO_SPEED_FREQ_HIGH;
90
+	
91
+	HAL_GPIO_Init(GPIOC, &gpioInit);
92
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_RESET);
93
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_RESET);
94
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET);
95
+	
96
+	__HAL_RCC_GPIOA_CLK_ENABLE();
97
+	
98
+	gpioInit.Pin = (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
99
+	gpioInit.Mode = GPIO_MODE_OUTPUT_PP;
100
+	gpioInit.Pull = GPIO_NOPULL;
101
+	gpioInit.Speed = GPIO_SPEED_FREQ_HIGH;
102
+	
103
+	HAL_GPIO_Init(GPIOA, &gpioInit);
104
+	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
105
+	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
106
+	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
107
+	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
108
+	
109
+	__HAL_RCC_GPIOD_CLK_ENABLE();
110
+	
111
+	gpioInit.Pin = GPIO_PIN_2;
112
+	gpioInit.Mode = GPIO_MODE_INPUT;
113
+	gpioInit.Pull = GPIO_PULLDOWN;
114
+	gpioInit.Speed = GPIO_SPEED_FREQ_HIGH;
115
+	
116
+	HAL_GPIO_Init(GPIOD, &gpioInit);
117
+	
118
+	for(int i = 0; i < KEYBOARD_ROW_QUANTITY; i++)
119
+	{
120
+		for(int j = 0; j < KEYBOARD_COLUMN_QUANTITY; j++)
121
+		{
122
+			keyLastStatus[i][j] = FALSE;
123
+		}
124
+	}
125
+}
126
+
127
+//! Process the keyboard fire event. It reads current keyboard status and adds new data to the input buffer.
128
+void keyboardFire(void)
129
+{
130
+	static unsigned char keyStatus[KEYBOARD_ROW_QUANTITY][KEYBOARD_COLUMN_QUANTITY];
131
+	
132
+	bool shift = FALSE;
133
+	bool ctrl = FALSE;
134
+	
135
+	unsigned char localBuffer[KEYBOARD_LOCAL_BUFFER_SIZE];
136
+	unsigned char localBufferEnd = 0;
137
+	
138
+	for(int i = 0; i < KEYBOARD_ROW_QUANTITY; i++)
139
+	{
140
+		for(int j = 0; j < KEYBOARD_COLUMN_QUANTITY; j++)
141
+		{
142
+			keyStatus[i][j] = 0;
143
+		}
144
+	}
145
+	
146
+	for(int retry = 0; retry < KEYBOARD_STATUS_RETRY; retry++)
147
+	{
148
+		for(int i = 0; i < KEYBOARD_ROW_QUANTITY; i++)
149
+		{
150
+			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, ((i & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET));
151
+			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, ((i & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET));
152
+			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, ((i & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET));
153
+			
154
+			for(int j = 0; j < KEYBOARD_COLUMN_QUANTITY; j++)
155
+			{
156
+				HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, ((j & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET));
157
+				HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, ((j & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET));
158
+				HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, ((j & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET));
159
+				HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, ((j & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET));
160
+				
161
+				// wait
162
+				{
163
+					volatile int w = 15;
164
+					while(w--);
165
+				}
166
+				
167
+				if(HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_2) == GPIO_PIN_SET)
168
+				{
169
+					keyStatus[i][j]++;
170
+				}
171
+			}
172
+		}
173
+	}
174
+	
175
+	if(keyStatus[KEYBOARD_POS_SHIFT_LEFT_ROW][KEYBOARD_POS_SHIFT_LEFT_COLUMN] >= KEYBOARD_STATUS_MIN)
176
+	{
177
+		shift = TRUE;
178
+	}
179
+	else if(keyStatus[KEYBOARD_POS_SHIFT_RIGHT_ROW][KEYBOARD_POS_SHIFT_RIGHT_COLUMN] >= KEYBOARD_STATUS_MIN)
180
+	{
181
+		shift = TRUE;
182
+	}
183
+	
184
+	if(keyStatus[KEYBOARD_POS_CAPSLOCK_ROW][KEYBOARD_POS_CAPSLOCK_COLUMN] >= KEYBOARD_STATUS_MIN)
185
+	{
186
+		if(!(keyLastStatus[KEYBOARD_POS_CAPSLOCK_ROW][KEYBOARD_POS_CAPSLOCK_COLUMN]))
187
+		{
188
+			if(capslock)
189
+			{
190
+				ledSetCapslock(FALSE);
191
+				capslock = FALSE;
192
+			}
193
+			else
194
+			{
195
+				ledSetCapslock(TRUE);
196
+				capslock = TRUE;
197
+			}
198
+			
199
+			keyLastStatus[KEYBOARD_POS_CAPSLOCK_ROW][KEYBOARD_POS_CAPSLOCK_COLUMN] = TRUE;
200
+		}
201
+	}
202
+	else
203
+	{
204
+		keyLastStatus[KEYBOARD_POS_CAPSLOCK_ROW][KEYBOARD_POS_CAPSLOCK_COLUMN] = FALSE;
205
+	}
206
+	
207
+	if(keyStatus[KEYBOARD_POS_CTRL_ROW][KEYBOARD_POS_CTRL_COLUMN] >= KEYBOARD_STATUS_MIN)
208
+	{
209
+		ctrl = TRUE;
210
+	}
211
+	
212
+	for(int i = 0; i < KEYBOARD_ROW_QUANTITY; i++)
213
+	{
214
+		for(int j = 0; j < KEYBOARD_COLUMN_QUANTITY; j++)
215
+		{
216
+			if((keyCode[0][i][j] > 0x00) && (keyCode[0][i][j] < 0xff))
217
+			{
218
+				if(keyStatus[i][j] >= KEYBOARD_STATUS_MIN)
219
+				{
220
+					if(!(keyLastStatus[i][j]))
221
+					{
222
+						unsigned char key;
223
+						
224
+						if(((!capslock) && shift) || (capslock && (!shift)))
225
+						{
226
+							key = keyCode[1][i][j];
227
+						}
228
+						else
229
+						{
230
+							key = keyCode[0][i][j];
231
+						}
232
+						
233
+						if(ctrl && (key >= KEYBOARD_CTRL_MIN_CODE))
234
+						{
235
+							key |= KEYBOARD_CTRL_MASK;
236
+						}
237
+						
238
+						if(localBufferEnd < KEYBOARD_LOCAL_BUFFER_SIZE)
239
+						{
240
+							localBuffer[localBufferEnd] = key;
241
+							
242
+							localBufferEnd++;
243
+						}
244
+						
245
+						keyLastStatus[i][j] = TRUE;
246
+					}
247
+				}
248
+				else
249
+				{
250
+					keyLastStatus[i][j] = FALSE;
251
+				}
252
+			}
253
+		}
254
+	}
255
+	
256
+	for(int i = 0; i < localBufferEnd; i++)
257
+	{
258
+		__disable_irq();
259
+		{
260
+			if(bufferStart == ((bufferEnd + 1) % KEYBOARD_BUFFER_SIZE))
261
+			{
262
+				__enable_irq();
263
+				break;
264
+			}
265
+			
266
+			buffer[bufferEnd] = localBuffer[i];
267
+			bufferEnd = ((bufferEnd + 1) % KEYBOARD_BUFFER_SIZE);
268
+		}
269
+		__enable_irq();
270
+	}
271
+}
272
+
273
+/**
274
+ * Read a next char from input buffer
275
+ *
276
+ * @return Next char from the input buffer
277
+ */
278
+unsigned char keyboardGetKey(void)
279
+{
280
+	__disable_irq();
281
+	if(bufferStart == bufferEnd)
282
+	{
283
+		__enable_irq();
284
+		return(0x00);
285
+	}
286
+	else
287
+	{
288
+		unsigned int first = bufferStart;
289
+		
290
+		bufferStart = ((first + 1) % KEYBOARD_BUFFER_SIZE);
291
+		
292
+		unsigned char val = buffer[first];
293
+		
294
+		__enable_irq();
295
+		return(val);
296
+	}
297
+}
298
+
299
+/**
300
+ * Check if is a new data in the input buffer
301
+ *
302
+ * @return Status of waiting data in the input buffer
303
+ */
304
+bool keyboardIsData(void)
305
+{
306
+	__disable_irq();
307
+	if(bufferStart == bufferEnd)
308
+	{
309
+		__enable_irq();
310
+		return(FALSE);
311
+	}
312
+	else
313
+	{
314
+		__enable_irq();
315
+		return(TRUE);
316
+	}
317
+}