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,259 @@
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 "font.h"
20
+
21
+#include "lcd.h"
22
+
23
+//! LCD buffer type list
24
+enum LCDBufferID
25
+{
26
+	LCD_BUFFER_WORK = 0, //!< Work buffer
27
+	LCD_BUFFER_READY, //!< Ready to display buffer
28
+	LCD_BUFFER_DISPLAY, //!< Display buffer used to generate an image on the LCD
29
+	LCD_BUFFER_QUANTITY //!< Quantity of the buffers
30
+};
31
+
32
+static volatile bool refreshRequest = FALSE; //!< Status of refresh request
33
+
34
+static unsigned char charBuffer[LCD_BUFFER_QUANTITY][LCD_HEIGHT][LCD_WIDTH]; //!< Char buffers
35
+static unsigned char colorBuffer[LCD_BUFFER_QUANTITY][LCD_HEIGHT][LCD_WIDTH]; //!< Background and foreground color buffers
36
+
37
+static void lcdCopyWorkBuffer(void);
38
+static void lcdCopyReadyBuffer(void);
39
+
40
+static void lcdDraw(void);
41
+static void lcdDrawLine(int lineNumber);
42
+
43
+//! Init LCD and set up buffers and output pins
44
+void lcdInit(void)
45
+{
46
+	__HAL_RCC_GPIOC_CLK_ENABLE();
47
+	
48
+	GPIO_InitTypeDef gpioInit = {0};
49
+	
50
+	gpioInit.Pin = (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8);
51
+	gpioInit.Mode = GPIO_MODE_OUTPUT_PP;
52
+	gpioInit.Pull = GPIO_NOPULL;
53
+	gpioInit.Speed = GPIO_SPEED_FREQ_HIGH;
54
+	
55
+	HAL_GPIO_Init(GPIOC, &gpioInit);
56
+	
57
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
58
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET);
59
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
60
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET);
61
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);
62
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
63
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
64
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
65
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);
66
+	
67
+	HAL_Delay(10);
68
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
69
+	HAL_Delay(10);
70
+	
71
+	lcdClear();
72
+	lcdRefresh();
73
+}
74
+
75
+//! Copy data from the canvas painting buffer to the ready to show buffer
76
+void lcdRefresh(void)
77
+{
78
+	lcdCopyWorkBuffer();
79
+	
80
+	__disable_irq();
81
+	refreshRequest = TRUE;
82
+	__enable_irq();
83
+}
84
+
85
+//! Clear the canvas painting buffer
86
+void lcdClear(void)
87
+{
88
+	for(int i = 0; i < LCD_HEIGHT; i++)
89
+	{
90
+		for(int j = 0; j < LCD_WIDTH; j++)
91
+		{
92
+			charBuffer[LCD_BUFFER_WORK][i][j] = 0;
93
+			colorBuffer[LCD_BUFFER_WORK][i][j] = 0;
94
+		}
95
+	}
96
+}
97
+
98
+/**
99
+ * Set char in the buffer
100
+ *
101
+ * @param c Char to set
102
+ * @param x Horizontal position in range 0-WIDTH
103
+ * @param y Vertical position in range 0-HEIGHT
104
+ * @param charColor Foreground color code in range 0-15
105
+ * @param backgroundColor Background color code in range 0-15
106
+ */
107
+void lcdSetChar(unsigned char c, unsigned int x, unsigned int y, unsigned char charColor, unsigned char backgroundColor)
108
+{
109
+	if((x < LCD_WIDTH) && (y < LCD_HEIGHT))
110
+	{
111
+		charBuffer[LCD_BUFFER_WORK][y][x] = c;
112
+		colorBuffer[LCD_BUFFER_WORK][y][x] = ((charColor & 0x0f) | (backgroundColor << 4));
113
+	}
114
+}
115
+
116
+//! Scroll the canvas painting buffer one line up
117
+void lcdScroll(void)
118
+{
119
+	for(int y = 0; y < (LCD_HEIGHT - 1); y++)
120
+	{
121
+		for(int x = 0; x < LCD_WIDTH; x++)
122
+		{
123
+			charBuffer[LCD_BUFFER_WORK][y][x] = charBuffer[LCD_BUFFER_WORK][y + 1][x];
124
+			colorBuffer[LCD_BUFFER_WORK][y][x] = colorBuffer[LCD_BUFFER_WORK][y + 1][x];
125
+		}
126
+	}
127
+	
128
+	for(int x = 0; x < LCD_WIDTH; x++)
129
+	{
130
+		charBuffer[LCD_BUFFER_WORK][LCD_HEIGHT - 1][x] = 0;
131
+		colorBuffer[LCD_BUFFER_WORK][LCD_HEIGHT - 1][x] = 0;
132
+	}
133
+}
134
+
135
+//! Infinity draw loop on the LCD. It works at background, and it refreshes the LCD when no other operation is in progress.
136
+void lcdDrawLoop(void)
137
+{
138
+	while(1)
139
+	{
140
+		if(refreshRequest)
141
+		{
142
+			__disable_irq();
143
+			{
144
+				lcdCopyReadyBuffer();
145
+				
146
+				refreshRequest = FALSE;
147
+			}
148
+			__enable_irq();
149
+			
150
+			lcdDraw();
151
+		}
152
+	}
153
+}
154
+
155
+//! Copy data from the work buffer to the ready buffer
156
+static void lcdCopyWorkBuffer(void)
157
+{
158
+	for(int i = 0; i < LCD_HEIGHT; i++)
159
+	{
160
+		for(int j = 0; j < LCD_WIDTH; j++)
161
+		{
162
+			charBuffer[LCD_BUFFER_READY][i][j] = charBuffer[LCD_BUFFER_WORK][i][j];
163
+			colorBuffer[LCD_BUFFER_READY][i][j] = colorBuffer[LCD_BUFFER_WORK][i][j];
164
+		}
165
+	}
166
+}
167
+
168
+//! Copy data from the ready buffer to the display buffer
169
+static void lcdCopyReadyBuffer(void)
170
+{
171
+	for(int i = 0; i < LCD_HEIGHT; i++)
172
+	{
173
+		for(int j = 0; j < LCD_WIDTH; j++)
174
+		{
175
+			charBuffer[LCD_BUFFER_DISPLAY][i][j] = charBuffer[LCD_BUFFER_READY][i][j];
176
+			colorBuffer[LCD_BUFFER_DISPLAY][i][j] = colorBuffer[LCD_BUFFER_READY][i][j];
177
+		}
178
+	}
179
+}
180
+
181
+//! Draw a whole buffer on the LCD
182
+static void lcdDraw(void)
183
+{
184
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
185
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET);
186
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
187
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET);
188
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET);
189
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
190
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
191
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
192
+
193
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);
194
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
195
+	
196
+	for(int i = 0; i < 4; i++)
197
+	{
198
+		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
199
+		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
200
+	}
201
+
202
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);
203
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
204
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
205
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
206
+
207
+	for(int i = 0; i < LCD_HEIGHT; i++)
208
+	{
209
+		lcdDrawLine(i);
210
+	}
211
+	
212
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET);
213
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
214
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
215
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
216
+}
217
+
218
+/**
219
+ * Draw a one line on the LCD
220
+ *
221
+ * @param lineNumber Row number to draw on the LCD
222
+ */
223
+static void lcdDrawLine(int lineNumber)
224
+{
225
+	for(int i = 0; i < (LCD_CHAR_HEIGHT * 2); i++)
226
+	{
227
+		int row = lineNumber;
228
+		int fontRow = (i / 2);
229
+		
230
+		for(int column = 0; column < LCD_WIDTH; column++)
231
+		{
232
+			unsigned char c = charBuffer[LCD_BUFFER_DISPLAY][row][column];
233
+			unsigned char b = font[c][fontRow];
234
+			
235
+			unsigned char colorChar = (colorBuffer[LCD_BUFFER_DISPLAY][row][column] & 0x0f);
236
+			unsigned char colorBackground = ((colorBuffer[LCD_BUFFER_DISPLAY][row][column] >> 4) & 0x0f);
237
+			
238
+			for(int k = 0; k < LCD_CHAR_WIDTH; k++)
239
+			{
240
+				if(b & 0x01)
241
+				{
242
+					GPIOC->ODR = ((GPIOC->ODR & 0xff00) | 0xa0 | colorChar);
243
+					GPIOC->BSRR = 0x40;
244
+					GPIOC->BRR = 0x40;
245
+					GPIOC->BSRR = 0x40;
246
+				}
247
+				else
248
+				{
249
+					GPIOC->ODR = ((GPIOC->ODR & 0xff00) | 0xa0 | colorBackground);
250
+					GPIOC->BSRR = 0x40;
251
+					GPIOC->BRR = 0x40;
252
+					GPIOC->BSRR = 0x40;
253
+				}
254
+				
255
+				b >>= 1;
256
+			}
257
+		}
258
+	}
259
+}