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,342 @@
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 <stm32f0xx_hal_spi.h>
17
+#include <system_stm32f0xx.h>
18
+
19
+#include "type.h"
20
+
21
+#include "flash.h"
22
+
23
+#define FLASH_TIMEOUT 100 //!< SPI HAL maximum time to process an operation
24
+
25
+#define FLASH_REG_STATUS 0xD7 //!< Status register address for the flash
26
+
27
+#define FLASH_STATUS_READY 0x80 //!< Ready status bit of the flash
28
+#define FLASH_STATUS_PAGE_SIZE_512 0x01 //!< 512 bytes sector is set bit of the flash
29
+
30
+#define FLASH_READ_SECTOR 0x53 //!< Read data from the flash to the internal buffer operation code
31
+#define FLASH_WRITE_SECTOR 0x83 //!< Write data from the internal buffer to the flash operation code
32
+
33
+#define FLASH_READ_BUFFER 0xd4 //!< Read data from the internal buffer operation code
34
+#define FLASH_WRITE_BUFFER 0x84 //!< Write data to the internal buffer operation code
35
+
36
+static void flashLock(void);
37
+static void flashUnlock(void);
38
+
39
+static unsigned char flashGetStatus(void);
40
+
41
+static bool flashReadSector(unsigned int sector);
42
+static bool flashWriteSector(unsigned int sector);
43
+
44
+static bool flashReadBuffer(unsigned int sector, unsigned char *buffer);
45
+static bool flashWriteBuffer(unsigned int sector, unsigned char *buffer);
46
+
47
+static SPI_HandleTypeDef spiHandle; //!< SPI HAL handle
48
+
49
+static volatile bool mutex; //!< Mutex lock for operations on the flash
50
+
51
+//! Init flash and set up the SPI
52
+void flashInit(void)
53
+{
54
+	__HAL_RCC_GPIOC_CLK_ENABLE();
55
+	
56
+	GPIO_InitTypeDef gpioInit = {0};
57
+	
58
+	gpioInit.Pin = GPIO_PIN_13;
59
+	gpioInit.Mode = GPIO_MODE_OUTPUT_PP;
60
+	gpioInit.Pull = GPIO_NOPULL;
61
+	gpioInit.Speed = GPIO_SPEED_FREQ_LOW;
62
+	
63
+	HAL_GPIO_Init(GPIOC, &gpioInit);
64
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
65
+	
66
+	__HAL_RCC_GPIOA_CLK_ENABLE();
67
+	
68
+	gpioInit.Pin = (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
69
+	gpioInit.Mode = GPIO_MODE_AF_PP;
70
+	gpioInit.Pull = GPIO_NOPULL;
71
+	gpioInit.Speed = GPIO_SPEED_FREQ_HIGH;
72
+	gpioInit.Alternate = GPIO_AF0_SPI2;
73
+	
74
+	HAL_GPIO_Init(GPIOA, &gpioInit);
75
+	
76
+	__HAL_RCC_SPI1_CLK_ENABLE();
77
+	
78
+	spiHandle.Instance = SPI1;
79
+	spiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
80
+	spiHandle.Init.Mode = SPI_MODE_MASTER;
81
+	spiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
82
+	spiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
83
+	spiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
84
+	spiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
85
+	spiHandle.Init.Direction = SPI_DIRECTION_2LINES;
86
+	spiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
87
+	spiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
88
+	spiHandle.Init.CRCPolynomial = 7;
89
+	spiHandle.Init.NSS = SPI_NSS_SOFT;
90
+	
91
+	HAL_SPI_Init(&spiHandle);
92
+	__HAL_SPI_ENABLE(&spiHandle);
93
+	
94
+	while(1)
95
+	{
96
+		unsigned char status = flashGetStatus();
97
+		
98
+		if(!(status & FLASH_STATUS_READY))
99
+		{
100
+			continue;
101
+		}
102
+		
103
+		if(!(status & FLASH_STATUS_PAGE_SIZE_512))
104
+		{
105
+			unsigned char buf[4] = { 0x3d, 0x2a, 0x80, 0xa6 };
106
+			
107
+			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
108
+			HAL_SPI_Transmit(&spiHandle, buf, 4, FLASH_TIMEOUT);
109
+			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
110
+		}
111
+		else
112
+		{
113
+			break;
114
+		}	
115
+	}
116
+}
117
+
118
+/**
119
+ * Read a sector data from the flash
120
+ *
121
+ * @param sector Sector number
122
+ * @param buffer Buffer to write data from the flash
123
+ *
124
+ * @return Status of the operation
125
+ */
126
+bool flashRead(unsigned int sector, unsigned char *buffer)
127
+{
128
+	flashLock();
129
+	
130
+	if(sector > FLASH_SECTOR_QUANTITY)
131
+	{
132
+		return(FALSE);
133
+	}
134
+	
135
+	if(!flashReadBuffer(sector, buffer))
136
+	{
137
+		flashUnlock();
138
+		
139
+		return(FALSE);
140
+	}
141
+	
142
+	flashUnlock();
143
+
144
+	return(TRUE);
145
+}
146
+
147
+/**
148
+ * Write a sector data to the flash
149
+ *
150
+ * @param sector Sector number
151
+ * @param buffer Buffer with data to write into the flash
152
+ *
153
+ * @return Status of the operation
154
+ */
155
+bool flashWrite(unsigned int sector, unsigned char *buffer)
156
+{
157
+	flashLock();
158
+	
159
+	if(sector > FLASH_SECTOR_QUANTITY)
160
+	{
161
+		return(FALSE);
162
+	}
163
+	
164
+	if(!flashWriteBuffer(sector, buffer))
165
+	{
166
+		flashUnlock();
167
+		
168
+		return(FALSE);
169
+	}
170
+	
171
+	flashUnlock();
172
+	
173
+	return(TRUE);
174
+}
175
+
176
+//! Lock access to the flash
177
+static void flashLock(void)
178
+{
179
+	while(1)
180
+	{
181
+		__disable_irq();
182
+		if(!mutex)
183
+		{
184
+			mutex = TRUE;
185
+			
186
+			break;
187
+		}
188
+		__enable_irq();
189
+		
190
+		for(volatile int i = 0; i < 100; i++);
191
+	}
192
+}
193
+
194
+//! Unlock access to the flash
195
+static void flashUnlock(void)
196
+{
197
+	__disable_irq();
198
+	{
199
+		mutex = FALSE;
200
+	}
201
+	__enable_irq();
202
+}
203
+
204
+/**
205
+ * Get status of the flash
206
+ *
207
+ * @return Status of the flash
208
+ */
209
+static unsigned char flashGetStatus(void)
210
+{
211
+	unsigned char address = FLASH_REG_STATUS;
212
+	unsigned char status = 0;
213
+	
214
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
215
+	HAL_SPI_Transmit(&spiHandle, &address, 1, FLASH_TIMEOUT);
216
+	HAL_SPI_Receive(&spiHandle, &status, 1, FLASH_TIMEOUT);
217
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
218
+
219
+	return(status);
220
+}
221
+
222
+/**
223
+ * Read a sector data from the flash to the internal buffer of the flash
224
+ *
225
+ * @param sector Sector number
226
+ *
227
+ * @return Status of the operation
228
+ */
229
+static bool flashReadSector(unsigned int sector)
230
+{
231
+	if(sector >= FLASH_SECTOR_QUANTITY)
232
+	{
233
+		return(FALSE);
234
+	}
235
+	
236
+	unsigned char buf[4] = { FLASH_READ_SECTOR, (unsigned char)((sector >> 7) & 0x7f), (unsigned char)((sector << 1) & 0xfe), 0x00 };
237
+	
238
+	while(!(flashGetStatus() & FLASH_STATUS_READY));
239
+	
240
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
241
+	HAL_SPI_Transmit(&spiHandle, buf, 4, FLASH_TIMEOUT);
242
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
243
+	
244
+	while(!(flashGetStatus() & FLASH_STATUS_READY));
245
+	
246
+	return(TRUE);
247
+}
248
+
249
+/**
250
+ * Write a sector data from the internal buffer of the flash to the flash
251
+ *
252
+ * @param sector Sector number
253
+ *
254
+ * @return Status of the operation
255
+ */
256
+static bool flashWriteSector(unsigned int sector)
257
+{
258
+	if(sector >= FLASH_SECTOR_QUANTITY)
259
+	{
260
+		return(FALSE);
261
+	}
262
+	
263
+	unsigned char buf[4] = { FLASH_WRITE_SECTOR, (unsigned char)((sector >> 7) & 0x7f), (unsigned char)((sector << 1) & 0xfe), 0x00 };
264
+	
265
+	while(!(flashGetStatus() & FLASH_STATUS_READY));
266
+	
267
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
268
+	HAL_SPI_Transmit(&spiHandle, buf, 4, FLASH_TIMEOUT);
269
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
270
+	
271
+	while(!(flashGetStatus() & FLASH_STATUS_READY));
272
+	
273
+	return(TRUE);
274
+}
275
+
276
+/**
277
+ * Read a sector data from the internal buffer of the flash
278
+ *
279
+ * @param sector Sector number
280
+ * @param buffer Buffer to write data from the internal buffer of the flash
281
+ *
282
+ * @return Status of the operation
283
+ */
284
+static bool flashReadBuffer(unsigned int sector, unsigned char *buffer)
285
+{
286
+	if(sector >= FLASH_SECTOR_QUANTITY)
287
+	{
288
+		return(FALSE);
289
+	}
290
+	
291
+	if(!flashReadSector(sector))
292
+	{
293
+		return(FALSE);
294
+	}
295
+	
296
+	unsigned char buf[5] = { FLASH_READ_BUFFER, 0x00, 0x00, 0x00, 0x00 };
297
+	
298
+	while(!(flashGetStatus() & FLASH_STATUS_READY));
299
+	
300
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
301
+	HAL_SPI_Transmit(&spiHandle, buf, 5, FLASH_TIMEOUT);
302
+	HAL_SPI_Receive(&spiHandle, buffer, FLASH_SECTOR_SIZE, FLASH_TIMEOUT);
303
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
304
+	
305
+	while(!(flashGetStatus() & FLASH_STATUS_READY));
306
+	
307
+	return(TRUE);
308
+}
309
+
310
+/**
311
+ * Write a sector data into the internal buffer of the flash
312
+ *
313
+ * @param sector Sector number
314
+ * @param buffer Buffer with data to write into the internal buffer of the flash
315
+ *
316
+ * @return Status of the operation
317
+ */
318
+static bool flashWriteBuffer(unsigned int sector, unsigned char *buffer)
319
+{
320
+	if(sector >= FLASH_SECTOR_QUANTITY)
321
+	{
322
+		return(FALSE);
323
+	}
324
+	
325
+	unsigned char buf[4] = { FLASH_WRITE_BUFFER, 0x00, 0x00, 0x00 };
326
+	
327
+	while(!(flashGetStatus() & FLASH_STATUS_READY));
328
+	
329
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
330
+	HAL_SPI_Transmit(&spiHandle, buf, 4, FLASH_TIMEOUT);
331
+	HAL_SPI_Transmit(&spiHandle, buffer, FLASH_SECTOR_SIZE, FLASH_TIMEOUT);
332
+	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
333
+	
334
+	while(!(flashGetStatus() & FLASH_STATUS_READY));
335
+	
336
+	if(!flashWriteSector(sector))
337
+	{
338
+		return(FALSE);
339
+	}
340
+	
341
+	return(TRUE);
342
+}