@@ -267,33 +267,90 @@ uint8_t ll_cam_get_dma_align(cam_obj_t *cam)
267
267
return 16 << GDMA .in [cam -> dma_num ].conf1 .in_ext_mem_bk_size ;
268
268
}
269
269
270
- void ll_cam_dma_sizes (cam_obj_t * cam )
271
- {
272
- int cnt = 0 ;
270
+ static void ll_cam_calc_rgb_dma (cam_obj_t * cam ){
271
+ size_t node_max = LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE / cam -> dma_bytes_per_item ;
272
+ size_t line_width = cam -> width * cam -> in_bytes_per_pixel ;
273
+ size_t node_size = node_max ;
274
+ size_t nodes_per_line = 1 ;
275
+ size_t lines_per_node = 1 ;
276
+
277
+ // Calculate DMA Node Size so that it's divisable by or divisor of the line width
278
+ if (line_width >= node_max ){
279
+ // One or more nodes will be requied for one line
280
+ for (size_t i = node_max ; i > 0 ; i = i - 1 ){
281
+ if ((line_width % i ) == 0 ) {
282
+ node_size = i ;
283
+ nodes_per_line = line_width / node_size ;
284
+ break ;
285
+ }
286
+ }
287
+ } else {
288
+ // One or more lines can fit into one node
289
+ for (size_t i = node_max ; i > 0 ; i = i - 1 ){
290
+ if ((i % line_width ) == 0 ) {
291
+ node_size = i ;
292
+ lines_per_node = node_size / line_width ;
293
+ while ((cam -> height % lines_per_node ) != 0 ){
294
+ lines_per_node = lines_per_node - 1 ;
295
+ node_size = lines_per_node * line_width ;
296
+ }
297
+ break ;
298
+ }
299
+ }
300
+ }
301
+
302
+ ESP_LOGI (TAG , "node_size: %4u, nodes_per_line: %u, lines_per_node: %u" ,
303
+ node_size * cam -> dma_bytes_per_item , nodes_per_line , lines_per_node );
304
+
305
+ cam -> dma_node_buffer_size = node_size * cam -> dma_bytes_per_item ;
306
+
307
+ size_t dma_half_buffer_max = 16 * 1024 / cam -> dma_bytes_per_item ;
308
+ if (line_width > dma_half_buffer_max ) {
309
+ ESP_LOGE (TAG , "Resolution too high" );
310
+ return ;
311
+ }
312
+
313
+ // Calculate minimum EOF size = max(mode_size, line_size)
314
+ size_t dma_half_buffer_min = node_size * nodes_per_line ;
315
+
316
+ // Calculate max EOF size divisable by node size
317
+ size_t dma_half_buffer = (dma_half_buffer_max / dma_half_buffer_min ) * dma_half_buffer_min ;
318
+
319
+ // Adjust EOF size so that height will be divisable by the number of lines in each EOF
320
+ size_t lines_per_half_buffer = dma_half_buffer / line_width ;
321
+ while ((cam -> height % lines_per_half_buffer ) != 0 ){
322
+ dma_half_buffer = dma_half_buffer - dma_half_buffer_min ;
323
+ lines_per_half_buffer = dma_half_buffer / line_width ;
324
+ }
325
+
326
+ // Calculate DMA size
327
+ size_t dma_buffer_max = 2 * dma_half_buffer_max ;
328
+ if (cam -> psram_mode ) {
329
+ dma_buffer_max = cam -> recv_size / cam -> dma_bytes_per_item ;
330
+ }
331
+ size_t dma_buffer_size = dma_buffer_max ;
332
+ if (!cam -> psram_mode ) {
333
+ dma_buffer_size = (dma_buffer_max / dma_half_buffer ) * dma_half_buffer ;
334
+ }
273
335
336
+ ESP_LOGI (TAG , "dma_half_buffer_min: %5u, dma_half_buffer: %5u, lines_per_half_buffer: %2u, dma_buffer_size: %5u" ,
337
+ dma_half_buffer_min * cam -> dma_bytes_per_item , dma_half_buffer * cam -> dma_bytes_per_item , lines_per_half_buffer , dma_buffer_size * cam -> dma_bytes_per_item );
338
+
339
+ cam -> dma_buffer_size = dma_buffer_size * cam -> dma_bytes_per_item ;
340
+ cam -> dma_half_buffer_size = dma_half_buffer * cam -> dma_bytes_per_item ;
341
+ cam -> dma_half_buffer_cnt = cam -> dma_buffer_size / cam -> dma_half_buffer_size ;
342
+ }
343
+
344
+ void ll_cam_dma_sizes (cam_obj_t * cam )
345
+ {
274
346
cam -> dma_bytes_per_item = 1 ;
275
347
if (cam -> jpeg_mode ) {
276
348
cam -> dma_half_buffer_cnt = 16 ;
277
349
cam -> dma_buffer_size = cam -> dma_half_buffer_cnt * 1024 ;
278
350
cam -> dma_half_buffer_size = cam -> dma_buffer_size / cam -> dma_half_buffer_cnt ;
279
351
cam -> dma_node_buffer_size = cam -> dma_half_buffer_size ;
280
352
} else {
281
- int max_cam_rec_data_bytelen = 16384 ;
282
- for (cnt = 0 ; cnt < max_cam_rec_data_bytelen ; cnt ++ ) {
283
- if (cam -> recv_size % (max_cam_rec_data_bytelen - cnt ) == 0 ) {
284
- break ;
285
- }
286
- }
287
- cam -> dma_buffer_size = cam -> recv_size ;
288
- cam -> dma_half_buffer_size = max_cam_rec_data_bytelen - cnt ;
289
- cam -> dma_half_buffer_cnt = cam -> dma_buffer_size / cam -> dma_half_buffer_size ;
290
-
291
- for (cnt = 0 ; cnt < LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE ; cnt ++ ) { // Find a divisible dma size
292
- if ((cam -> dma_half_buffer_size ) % (LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE - cnt ) == 0 ) {
293
- break ;
294
- }
295
- }
296
- cam -> dma_node_buffer_size = LCD_CAM_DMA_NODE_BUFFER_MAX_SIZE - cnt ;
353
+ ll_cam_calc_rgb_dma (cam );
297
354
}
298
355
}
299
356
0 commit comments