1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
22
23
26
27
28
29
30
31
32
33
34
35
36
37
39
40
44
45
46
47
56
57
58
63
64
65
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
125
126
127
128
129
130
131
132
133
134
135
136
137
152
153
154
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
189
190
191
192
193
194
195
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
228
238
239
244
262
263
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
306
307
308
309
310
311
312
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
350
351
352
358
384
385
390
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
471
/* ... */
#include "main.h"
Includes
#define PRESSED_FIRST 0x00
Private define
uint8_t ubPressedButton = PRESSED_FIRST;
FATFS MSC_FatFs;
FIL MyFile;
char MSC_Path[4];
USBH_HandleTypeDef hUSBHost;
const uint32_t aBMPHeader[14]=
{0xFA364D42, 0x00000005, 0x00360000, 0x00280000, 0x01E00000, 0x01100000, 0x00010000,
0x00000018, 0xF5400000, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x0000...};
typedef enum {
STORAGE_IDLE = 0,
STORAGE_READY,
...}MSC_ApplicationTypeDef;
MSC_ApplicationTypeDef Appli_state = STORAGE_IDLE;
Private variables
static void SystemClock_Config(void);
static void PicturePrepare(void);
static void Error_Handler(void);
static void SavePicture(void);
static void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst);
static void CAMERA_Capture(void);
static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id);
Private function prototypes
/* ... */
int main(void)
{
/* ... */
HAL_Init();
SystemClock_Config();
BSP_LED_Init(LED1);
BSP_LED_Init(LED3);
USBH_Init(&hUSBHost, USBH_UserProcess, 0);
USBH_RegisterClass(&hUSBHost, USBH_MSC_CLASS);
USBH_Start(&hUSBHost);
/* ... */
BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_SPEAKER, 70, AUDIO_FREQUENCY_48K);
AUDIO_IO_Write(AUDIO_I2C_ADDRESS, 0x200, 0);
AUDIO_IO_Write(AUDIO_I2C_ADDRESS, 0x300, 0x6010);
BSP_PB_Init(BUTTON_TAMPER, BUTTON_MODE_GPIO);
FATFS_LinkDriver(&USBH_Driver, MSC_Path);
BSP_LCD_Init();
BSP_LCD_LayerDefaultInit(1, LCD_FRAME_BUFFER_LAYER1);
BSP_LCD_SelectLayer(1);
BSP_LCD_Clear(LCD_COLOR_WHITE);
BSP_LCD_SetLayerVisible(1, DISABLE);
BSP_LCD_LayerDefaultInit(0, LCD_FRAME_BUFFER);
BSP_LCD_DisplayOn();
BSP_LCD_SelectLayer(0);
BSP_LCD_Clear(LCD_COLOR_WHITE);
BSP_CAMERA_Init(RESOLUTION_R480x272);
BSP_CAMERA_ContinuousStart((uint8_t *)CAMERA_FRAME_BUFFER);
while (1)
{
USBH_Process(&hUSBHost);
switch(Appli_state)
{
case STORAGE_READY:
CAMERA_Capture();
break;
case STORAGE_READY:
case STORAGE_IDLE:
break; case STORAGE_IDLE:
}switch (Appli_state) { ... }
}while (1) { ... }
}{ ... }
/* ... */
static void SavePicture(void)
{
FRESULT res1, res2;
uint32_t byteswritten;
static uint32_t counter = 0;
uint8_t str[30];
BSP_CAMERA_Suspend();
PicturePrepare();
BSP_LCD_SetLayerVisible(1, ENABLE);
BSP_LCD_SetColorKeying(1, LCD_COLOR_WHITE);
BSP_LCD_SelectLayer(1);
BSP_LCD_SetTextColor(LCD_COLOR_DARKRED);
BSP_LCD_SetFont(&Font24);
sprintf((char *)str,"image_%d.bmp", (int)counter);
BSP_LCD_DisplayStringAt(20, (BSP_LCD_GetYSize() - 24), (uint8_t *)"Saving ..", RIGHT_MODE);
if(f_open(&MyFile, (const char*)str, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
{
Error_Handler();
}if (f_open(&MyFile, (const char*)str, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) { ... }
else
{
res1 = f_write(&MyFile, (uint32_t *)aBMPHeader, 54, (void *)&byteswritten);
res2 = f_write(&MyFile, (uint32_t *)CONVERTED_FRAME_BUFFER, (BSP_LCD_GetXSize()*BSP_LCD_GetYSize()*3), (void *)&byteswritten);
if((res1 != FR_OK) || (res2 != FR_OK) || (byteswritten == 0))
{
Error_Handler();
}if ((res1 != FR_OK) || (res2 != FR_OK) || (byteswritten == 0)) { ... }
else
{
f_close(&MyFile);
BSP_LED_On(LED1);
BSP_LCD_SetTextColor(LCD_COLOR_DARKGREEN);
BSP_LCD_DisplayStringAt(20, (BSP_LCD_GetYSize()-24), (uint8_t *)" Saved ", RIGHT_MODE);
HAL_Delay(2000);
BSP_LCD_SetLayerVisible(1, DISABLE);
BSP_LCD_SelectLayer(0);
counter++;
BSP_LED_Off(LED1);
BSP_CAMERA_Resume();
}else { ... }
}else { ... }
}{ ... }
/* ... */
static void CAMERA_Capture(void)
{
while(1)
{
if(BSP_PB_GetState(BUTTON_TAMPER) != GPIO_PIN_SET)
{
SavePicture();
}if (BSP_PB_GetState(BUTTON_TAMPER) != GPIO_PIN_SET) { ... }
}while (1) { ... }
}{ ... }
/* ... */
void BSP_CAMERA_LineEventCallback(void)
{
static uint32_t camera_datapointer, lcd_datapointer, line_number;
if(BSP_LCD_GetYSize() > line_number)
{
LCD_LL_ConvertLineToARGB8888((uint32_t *)(CAMERA_FRAME_BUFFER + camera_datapointer), (uint32_t *)(LCD_FRAME_BUFFER + lcd_datapointer));
camera_datapointer = camera_datapointer + BSP_LCD_GetXSize() * (sizeof(uint16_t));
lcd_datapointer = lcd_datapointer + BSP_LCD_GetXSize() * (sizeof(uint32_t));
line_number++;
}if (BSP_LCD_GetYSize() > line_number) { ... }
else
{
camera_datapointer = 0;
lcd_datapointer = 0;
line_number = 0;
}else { ... }
}{ ... }
/* ... */
static void PicturePrepare(void)
{
static DMA2D_HandleTypeDef hdma2d_eval;
uint32_t address1 = CONVERTED_FRAME_BUFFER;
uint32_t address2 = LCD_FRAME_BUFFER;
uint32_t index = 0;
hdma2d_eval.Init.Mode = DMA2D_M2M_PFC;
hdma2d_eval.Init.ColorMode = DMA2D_RGB888;
hdma2d_eval.Init.OutputOffset = 0;
hdma2d_eval.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
hdma2d_eval.LayerCfg[1].InputAlpha = 0xFF;
hdma2d_eval.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
hdma2d_eval.LayerCfg[1].InputOffset = 0;
hdma2d_eval.Instance = DMA2D;
address2 += ((BSP_LCD_GetXSize() * (BSP_LCD_GetYSize() - 1)) * 4);
for(index = 0; index < (BSP_LCD_GetYSize()); index++)
{
if(HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK)
{
if(HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK)
{
if (HAL_DMA2D_Start(&hdma2d_eval, address2, address1, (BSP_LCD_GetXSize()), 1) == HAL_OK)
{
HAL_DMA2D_PollForTransfer(&hdma2d_eval, 10);
}if (HAL_DMA2D_Start(&hdma2d_eval, address2, address1, (BSP_LCD_GetXSize()), 1) == HAL_OK) { ... }
}if (HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK) { ... }
}if (HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK) { ... }
address1 += ((BSP_LCD_GetXSize())*3);
address2 -= BSP_LCD_GetXSize()*4;
}for (index = 0; index < (BSP_LCD_GetYSize()); index++) { ... }
}{ ... }
/* ... */
static void LCD_LL_ConvertLineToARGB8888(void *pSrc, void *pDst)
{
static DMA2D_HandleTypeDef hdma2d_eval;
__HAL_RCC_DMA2D_CLK_ENABLE();
hdma2d_eval.Init.Mode = DMA2D_M2M_PFC;
hdma2d_eval.Init.ColorMode = DMA2D_ARGB8888;
hdma2d_eval.Init.OutputOffset = 0;
hdma2d_eval.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
hdma2d_eval.LayerCfg[1].InputAlpha = 0xFF;
hdma2d_eval.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
hdma2d_eval.LayerCfg[1].InputOffset = 0;
hdma2d_eval.Instance = DMA2D;
if(HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK)
{
if(HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK)
{
if (HAL_DMA2D_Start(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, BSP_LCD_GetXSize(), 1) == HAL_OK)
{
HAL_DMA2D_PollForTransfer(&hdma2d_eval, 10);
}if (HAL_DMA2D_Start(&hdma2d_eval, (uint32_t)pSrc, (uint32_t)pDst, BSP_LCD_GetXSize(), 1) == HAL_OK) { ... }
}if (HAL_DMA2D_ConfigLayer(&hdma2d_eval, 1) == HAL_OK) { ... }
}if (HAL_DMA2D_Init(&hdma2d_eval) == HAL_OK) { ... }
}{ ... }
/* ... */
static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id)
{
switch (id)
{
case HOST_USER_SELECT_CONFIGURATION:
break;
case HOST_USER_SELECT_CONFIGURATION:
case HOST_USER_DISCONNECTION:
Appli_state = STORAGE_IDLE;
f_mount(NULL, (TCHAR const*)"", 0);
break;
case HOST_USER_DISCONNECTION:
case HOST_USER_CLASS_ACTIVE:
if(f_mount(&MSC_FatFs, (TCHAR const*)MSC_Path, 0) != FR_OK)
{
Error_Handler();
}if (f_mount(&MSC_FatFs, (TCHAR const*)MSC_Path, 0) != FR_OK) { ... }
else
{
Appli_state = STORAGE_READY;
}else { ... }
break;case HOST_USER_CLASS_ACTIVE:
}switch (id) { ... }
}{ ... }
/* ... */
static void Error_Handler(void)
{
BSP_LED_On(LED3);
BSP_LCD_SelectLayer(0);
while(1)
{
}while (1) { ... }
}{ ... }
/* ... */
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
/* ... */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}{ ... }
#ifdef USE_FULL_ASSERT
/* ... */
void assert_failed(uint8_t* file, uint32_t line)
{
/* ... */
while (1)
{
}while (1) { ... }
}assert_failed (uint8_t* file, uint32_t line) { ... }
/* ... */#endifPrivate functions