1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <common/bk_include.h>
16 #include <os/os.h>
17 #include <stdio.h>
18 #include <driver/media_types.h>
19 #include <driver/uvc_camera.h>
20 #include <os/mem.h>
21 #include "bk_usb.h"
22 #include <modules/usb.h>
23 #include <common/bk_err.h>
24 #include <driver/dma.h>
25 #include "bk_general_dma.h"
26
27 #include <driver/psram.h>
28 #include <driver/gpio.h>
29 #include "bk_misc.h"
30
31 #define TAG "uvc_drv"
32
33 #define UVC_LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
34 #define UVC_LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
35 #define UVC_LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
36 #define UVC_LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
37
38 #define USB_UVC_FIFO_ADDR (0x46002024)
39 #define UVC_DATA_LENGTH 512
40 #define USB_UVC_HEAD_LEN 12
41
42 //#define UVC_STRIP
43
44 void uvc_camera_memcpy_finish_callback(dma_id_t id);
45
46
47 beken_thread_t uvc_thread_drv_handle = NULL;
48 beken_queue_t uvc_drv_msg_que = NULL;
49 static const uvc_camera_config_t *uvc_camera_config = NULL;
50 static frame_buffer_t *curr_frame_buffer = NULL;
51 static uint8_t *uvc_rx_vstream_buffptr = NULL;
52 static uint8_t g_uvc_start = 0;
53 uint32_t uvc_frame_id = 0;
54
55 extern media_debug_t *media_debug;
56
57 #define FRAME_BUFFER_UVC (1024 * 5)
58
59 typedef struct
60 {
61 uint8_t frame_flag;
62 uint8_t sof;
63 uint8_t eof;
64 uint8_t uvc_dma;
65 uint8_t psram_dma;
66 uint32_t rxbuf_len;
67 uint32_t rx_read_len;
68 uint32_t uvc_transfer_len;
69 uint8_t *buffer;
70 frame_buffer_t *frame;
71 void (*node_full_handler)(void *curptr, uint32_t newlen, uint8_t is_eof, uint32_t frame_len);
72 } uvc_camera_drv_t;
73
74 uvc_camera_drv_t *uvc_camera_drv = NULL;
75
uvc_send_msg(uint8_t type,uint32_t data)76 static bk_err_t uvc_send_msg(uint8_t type, uint32_t data)
77 {
78 bk_err_t ret;
79 uvc_msg_t msg;
80
81 if (uvc_drv_msg_que)
82 {
83 msg.type = type;
84 msg.data = data;
85
86 ret = rtos_push_to_queue(&uvc_drv_msg_que, &msg, BEKEN_NO_WAIT);
87 if (kNoErr != ret)
88 {
89 UVC_LOGE("uvc_send_msg failed, type:%d\r\n", type);
90 return kOverrunErr;
91 }
92
93 return ret;
94 }
95 return kNoResourcesErr;
96 }
97
uvc_memcpy_by_chnl(void * out,const void * in,uint32_t len,dma_id_t cpy_chnls)98 static bk_err_t uvc_memcpy_by_chnl(void *out, const void *in, uint32_t len, dma_id_t cpy_chnls)
99 {
100 dma_config_t dma_config = {0};
101
102 dma_config.mode = DMA_WORK_MODE_SINGLE;
103 dma_config.chan_prio = 0;
104
105 dma_config.src.dev = DMA_DEV_DTCM;
106 dma_config.src.width = DMA_DATA_WIDTH_32BITS;
107 dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE;
108 dma_config.src.start_addr = (uint32_t)in;
109 dma_config.src.end_addr = (uint32_t)(in + len);
110
111 dma_config.dst.dev = DMA_DEV_DTCM;
112 dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
113 dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
114 dma_config.dst.start_addr = (uint32_t)out;
115 dma_config.dst.end_addr = (uint32_t)(out + len);
116
117 BK_LOG_ON_ERR(bk_dma_init(cpy_chnls, &dma_config));
118 BK_LOG_ON_ERR(bk_dma_set_transfer_len(cpy_chnls, len));
119
120 BK_LOG_ON_ERR(bk_dma_register_isr(cpy_chnls, NULL, uvc_camera_memcpy_finish_callback));
121 BK_LOG_ON_ERR(bk_dma_enable_finish_interrupt(cpy_chnls));
122 BK_LOG_ON_ERR(bk_dma_start(cpy_chnls));
123
124 return BK_OK;
125 }
126
127 #ifdef DVP_STRIP
uvc_frame_strip(frame_buffer_t * frame)128 static void uvc_frame_strip(frame_buffer_t *frame)
129 {
130 uint32_t i, strip = 0, strip_max = 50;
131
132 for (i = frame->length - 1; i > 0 && strip_max > 0; i--, strip_max--)
133 {
134 if (frame->frame[i] == 0xD9
135 && frame->frame[i - 1] == 0xFF)
136 {
137 break;
138 }
139 else
140 {
141 strip--;
142 }
143 }
144
145 if (strip_max)
146 {
147 frame->length -= strip;
148 }
149 else
150 {
151 UVC_LOGE("uvc_frame_strip error\n");
152 }
153 }
154 #endif
155
uvc_process_data_packet(void * curptr,uint32_t newlen,uint8_t is_eof,uint32_t frame_len)156 static void uvc_process_data_packet(void *curptr, uint32_t newlen, uint8_t is_eof, uint32_t frame_len)
157 {
158 uint8_t *data;
159 uint8_t bmhead_info;
160 uint32_t fack_len = frame_len;
161
162 if (curr_frame_buffer == NULL
163 || curr_frame_buffer->frame == NULL)
164 {
165 UVC_LOGE("%s curr_frame_buffer NULL\n");
166 return;
167 }
168
169 bmhead_info = *((uint8_t *)curptr + 1);
170 data = (uint8_t *)curptr + USB_UVC_HEAD_LEN;
171
172 if (bmhead_info & 0x40) // bit6 = 1, payload error
173 {
174 return;
175 }
176
177 if (frame_len & 0x3)
178 {
179 fack_len = ((frame_len >> 2) + 1) << 2;
180 //UVC_LOGI("eof %d-%d\r\n", frame_len, fack_len);
181 }
182
183 if (uvc_camera_drv->frame_flag != (bmhead_info & 0x01)) // bit0 fliped
184 {
185 uvc_camera_drv->frame_flag = (bmhead_info & 0x01);
186 if (uvc_camera_drv->sof || uvc_camera_drv->eof)
187 {
188 uvc_camera_drv->sof = false;
189 uvc_camera_drv->eof = false;
190 curr_frame_buffer->length = 0;
191 }
192 }
193
194 if (bmhead_info & 0x02) // bit1 = 1, end frame
195 {
196 /*uint8_t *eof;
197 eof = (uint8_t *)curptr + newlen - 2;
198 os_printf("%s, %02x, %02x\r\n", __func__, eof[0], eof[1]);*/
199 uvc_camera_drv->eof = true;
200 uvc_camera_drv->frame = curr_frame_buffer;
201 curr_frame_buffer->sequence = ++uvc_frame_id;
202 }
203 else
204 {
205 if ((frame_len > 0) && ((data[0] == 0xff) && (data[1] == 0xd8))) // strat frame
206 {
207 uvc_camera_drv->sof = true;
208 //UVC_LOGI("uvc start, %02x, %02x\r\n", data[0], data[1]);
209 }
210 }
211
212 if (frame_len > 0)
213 {
214 uvc_memcpy_by_chnl(curr_frame_buffer->frame + curr_frame_buffer->length, data, fack_len, uvc_camera_drv->psram_dma);
215 curr_frame_buffer->length += frame_len;
216 }
217 else if (frame_len == 0)
218 {
219 uvc_camera_memcpy_finish_callback(0);
220 }
221 }
222
uvc_camera_memcpy_finish_callback(dma_id_t id)223 void uvc_camera_memcpy_finish_callback(dma_id_t id)
224 {
225 if (uvc_camera_drv->eof == true)
226 {
227 if(uvc_camera_drv->sof == false)
228 {
229 curr_frame_buffer->length = 0;
230 return;
231 }
232 frame_buffer_t *frame = uvc_camera_drv->frame;
233
234 #ifdef DVP_STRIP
235 uvc_frame_strip(frame);
236 #endif
237
238 media_debug->isr_jpeg++;
239
240 uvc_camera_config->frame_complete(frame);
241 uvc_camera_drv->frame = NULL;
242 uvc_camera_drv->eof = false;
243 uvc_camera_drv->sof = false;
244
245 curr_frame_buffer = uvc_camera_config->frame_alloc();
246
247 if (curr_frame_buffer == NULL
248 || curr_frame_buffer->frame == NULL)
249 {
250 UVC_LOGE("alloc frame error\n");
251 return;
252 }
253
254 curr_frame_buffer->length = 0;
255 }
256 }
257
uvc_camera_dma_finish_callback(dma_id_t id)258 static void uvc_camera_dma_finish_callback(dma_id_t id)
259 {
260
261 uint32_t already_len = uvc_camera_drv->rx_read_len;
262 uint32_t copy_len = uvc_camera_drv->uvc_transfer_len;
263 uint32_t frame_len = uvc_camera_drv->uvc_transfer_len - USB_UVC_HEAD_LEN;
264 if (uvc_camera_drv->node_full_handler != NULL)
265 {
266 uvc_camera_drv->node_full_handler(uvc_camera_drv->buffer + already_len, copy_len, 0, frame_len);
267 }
268
269 already_len += copy_len;
270
271 if (already_len >= uvc_camera_drv->rxbuf_len)
272 {
273 already_len = 0;
274 }
275
276 uvc_camera_drv->rx_read_len = already_len;
277 }
278
uvc_dma_config(void)279 static bk_err_t uvc_dma_config(void)
280 {
281 bk_err_t ret = kNoErr;
282 curr_frame_buffer = uvc_camera_config->frame_alloc();
283
284 if (curr_frame_buffer == NULL)
285 {
286 UVC_LOGE("malloc frame fail \r\n");
287 ret = kNoResourcesErr;
288 return ret;
289 }
290
291 curr_frame_buffer->length = 0;
292
293 uvc_camera_drv->uvc_dma = bk_dma_alloc(DMA_DEV_USB);
294 if ((uvc_camera_drv->uvc_dma < DMA_ID_0) || (uvc_camera_drv->uvc_dma >= DMA_ID_MAX))
295 {
296 UVC_LOGE("malloc dma fail \r\n");
297 ret = kNoResourcesErr;
298 return ret;
299 }
300
301 dma_config_t dma_config = {0};
302 dma_config.mode = DMA_WORK_MODE_SINGLE;
303 dma_config.chan_prio = 0;
304 dma_config.src.dev = DMA_DEV_DTCM;//DMA_DEV_USB;
305 dma_config.src.width = DMA_DATA_WIDTH_32BITS;
306 dma_config.src.start_addr = USB_UVC_FIFO_ADDR;
307 dma_config.dst.dev = DMA_DEV_DTCM;
308 dma_config.dst.width = DMA_DATA_WIDTH_32BITS;
309 dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE;
310 dma_config.dst.start_addr = (uint32_t)uvc_camera_drv->buffer;
311 dma_config.dst.end_addr = (uint32_t)(uvc_camera_drv->buffer + FRAME_BUFFER_UVC * 2);
312
313 BK_LOG_ON_ERR(bk_dma_init(uvc_camera_drv->uvc_dma, &dma_config));
314 BK_LOG_ON_ERR(bk_dma_set_transfer_len(uvc_camera_drv->uvc_dma, FRAME_BUFFER_UVC));
315 BK_LOG_ON_ERR(bk_dma_register_isr(uvc_camera_drv->uvc_dma, NULL, uvc_camera_dma_finish_callback));
316 BK_LOG_ON_ERR(bk_dma_enable_finish_interrupt(uvc_camera_drv->uvc_dma));
317
318 return ret;
319 }
320
uvc_notify_uvc_configed_callback(void)321 static void uvc_notify_uvc_configed_callback(void)
322 {}
323
uvc_fiddle_rx_vs_callback(void)324 static void uvc_fiddle_rx_vs_callback(void)
325 {
326 if (g_uvc_start)
327 {
328 bk_uvc_receive_video_stream();
329 }
330 else
331 {
332 bk_uvc_stop();
333 }
334 }
335
uvc_disconnect_callback(void)336 static void uvc_disconnect_callback(void)
337 {
338 UVC_LOGI("uvc_disconnect\r\n");
339
340 if (uvc_camera_config && uvc_camera_config->uvc_disconnect)
341 {
342 uvc_camera_config->uvc_disconnect();
343 }
344
345 uvc_send_msg(UVC_EXIT, 0);
346
347 return;
348 }
349
uvc_get_packet_rx_vs_callback(uint8_t * arg,uint32_t count)350 static void uvc_get_packet_rx_vs_callback(uint8_t *arg, uint32_t count)
351 {
352 uint32_t left_len = 0;
353
354 bk_dma_set_src_start_addr(uvc_camera_drv->uvc_dma, (uint32_t)arg);
355 uvc_camera_drv->uvc_transfer_len = count;
356 left_len = uvc_camera_drv->rxbuf_len - uvc_camera_drv->rx_read_len;
357 if (left_len < uvc_camera_drv->uvc_transfer_len)
358 {
359 uvc_camera_drv->rx_read_len = 0;
360 }
361
362 uint32_t dest_start_addr = (uint32_t)(uvc_camera_drv->buffer + uvc_camera_drv->rx_read_len);
363 bk_dma_set_dest_start_addr(uvc_camera_drv->uvc_dma, dest_start_addr);
364 bk_dma_set_transfer_len(uvc_camera_drv->uvc_dma, uvc_camera_drv->uvc_transfer_len);
365 bk_dma_start(uvc_camera_drv->uvc_dma);
366 }
367
uvc_process_ppi_fps(const uvc_camera_device_t * config)368 static uint32_t uvc_process_ppi_fps(const uvc_camera_device_t *config)
369 {
370 uint32_t param = 0;
371 uint32_t resolution_id = UVC_FRAME_640_480;
372
373 UVC_LOGI("width:%d, height:%d, fps:%d\r\n", config->width, config->height, config->fps);
374 if ((config->width == 160) && (config->height == 120))
375 {
376 resolution_id = UVC_FRAME_160_120;
377 }
378 else if ((config->width == 176) && (config->height == 144))
379 {
380 resolution_id = UVC_FRAME_176_144;
381 }
382 else if ((config->width == 320) && (config->height == 240))
383 {
384 resolution_id = UVC_FRAME_320_240;
385 }
386 else if ((config->width == 352) && (config->height == 288))
387 {
388 resolution_id = UVC_FRAME_352_288;
389 }
390 else if ((config->width == 480) && (config->height == 320))
391 {
392 resolution_id = UVC_FRAME_480_320;
393 }
394 else if ((config->width == 480) && (config->height == 800))
395 {
396 resolution_id = UVC_FRAME_480_800;
397 }
398 else if ((config->width == 640) && (config->height == 320))
399 {
400 resolution_id = UVC_FRAME_640_320;
401 }
402 else if ((config->width == 640) && (config->height == 360))
403 {
404 resolution_id = UVC_FRAME_640_360;
405 }
406 else if ((config->width == 640) && (config->height == 480))
407 {
408 resolution_id = UVC_FRAME_640_480;
409 }
410 else if ((config->width == 800) && (config->height == 400))
411 {
412 resolution_id = UVC_FRAME_800_400;
413 }
414 else if ((config->width == 800) && (config->height == 480))
415 {
416 resolution_id = UVC_FRAME_800_480;
417 }
418 else if ((config->width == 800) && (config->height == 600))
419 {
420 resolution_id = UVC_FRAME_800_600;
421 }
422 else if ((config->width == 960) && (config->height == 540))
423 {
424 resolution_id = UVC_FRAME_960_540;
425 }
426 else if ((config->width == 1280) && (config->height == 720))
427 {
428 resolution_id = UVC_FRAME_1280_720;
429 }
430 else
431 {
432 UVC_LOGE("Not find this resolution, use default\r\n");
433 return 0;
434 }
435
436 if (config->fps < FPS_5 || config->fps > FPS_30)
437 {
438 UVC_LOGE("Set FPS unknow: %d\r\n", config->fps);
439 return 0;
440 }
441
442 param |= (resolution_id << 16);//bit[31-16]:ppi
443 param |= config->fps; // bit[15-0]:fps
444
445 return param;
446 }
447
uvc_set_ppi_fps(uint32_t data)448 static void uvc_set_ppi_fps(uint32_t data)
449 {
450 uint32_t resolution_id;
451 uint32_t fps;
452 bk_err_t status;
453 resolution_id = data >> 16;
454 fps = data & 0xFFFF;
455 status = bk_uvc_set_parameter(resolution_id, fps);
456 if (status != kNoErr)
457 {
458 os_printf("Set uvc param0 error!\r\n");
459 status = kOptionErr;
460 }
461
462 if (status != kNoErr)
463 {
464 uvc_send_msg(UVC_EXIT, 0);
465 }
466 }
467
uvc_set_start(uint32_t data)468 static void uvc_set_start(uint32_t data)
469 {
470 bk_err_t status = BK_OK;
471 g_uvc_start = 1;
472 status = bk_uvc_start();
473 if (status != BK_OK)
474 {
475 os_printf("start uvc error!\r\n");
476 uvc_send_msg(UVC_EXIT, 0);
477 }
478 }
479
uvc_set_stop(uint32_t data)480 static void uvc_set_stop(uint32_t data)
481 {
482 g_uvc_start = 0;
483 uvc_camera_drv->rx_read_len = 0;
484 }
485
uvc_camera_init(const uvc_camera_config_t * config)486 static bk_err_t uvc_camera_init(const uvc_camera_config_t *config)
487 {
488 uint32_t param;
489 void *parameter;
490 bk_err_t err = BK_OK;
491
492 media_debug->isr_jpeg = 0;
493
494 uvc_camera_config->frame_set_ppi((uint32_t)(uvc_camera_config->device->width) << 16 | uvc_camera_config->device->height, FRAME_JPEG);
495
496 // step 1: init dma, fifo to sharemem
497 err = uvc_dma_config();
498 if (err != BK_OK)
499 {
500 goto init_error;
501 }
502
503 // step 2: init dma, sharemem to frame_buffer
504 uvc_camera_drv->psram_dma = bk_dma_alloc(DMA_DEV_DTCM);
505 if ((uvc_camera_drv->psram_dma < DMA_ID_0) || (uvc_camera_drv->psram_dma >= DMA_ID_MAX))
506 {
507 UVC_LOGE("malloc uvc_camera_drv->psram_dma fail \r\n");
508 err = kNoResourcesErr;
509 goto init_error;
510 }
511
512 parameter = (void *)uvc_disconnect_callback;
513 bk_uvc_register_disconnect_callback(parameter);
514
515 parameter = (void *)uvc_notify_uvc_configed_callback;
516 err = bk_uvc_register_config_callback(parameter);
517 if (err != BK_OK)
518 {
519 os_printf("register uvc config callback error!\r\n");
520 goto init_error;
521 }
522
523 parameter = (void *)uvc_fiddle_rx_vs_callback;
524 err = bk_uvc_register_VSrxed_callback(parameter);
525 if (err != BK_OK)
526 {
527 os_printf("register uvc rx video stream callback error!\r\n");
528 goto init_error;
529 }
530
531 parameter = (void *)uvc_get_packet_rx_vs_callback;
532 err = bk_uvc_register_VSrxed_packet_callback(parameter);
533 if (err != BK_OK)
534 {
535 os_printf("register uvc rx every packet callback error!\r\n");
536 goto init_error;
537 }
538
539 uvc_rx_vstream_buffptr = (uint8_t *)os_malloc(128);
540 if (!uvc_rx_vstream_buffptr)
541 {
542 os_printf("malloc rx video stream buf error!\r\n");
543 goto init_error;
544 }
545
546 parameter = (void *)uvc_rx_vstream_buffptr;
547 err = bk_uvc_register_rx_vstream_buffptr(parameter);
548 if (err != BK_OK)
549 {
550 os_printf("uvc set rx video stream buf addr error!\r\n");
551 goto init_error;
552 }
553
554 param = 128;
555 err = bk_uvc_register_rx_vstream_bufflen(param);
556 if (err != BK_OK)
557 {
558 os_printf("uvc set rx video stream buf length error!\r\n");
559 goto init_error;
560 }
561
562 bk_uvc_register_link(0);
563 param = uvc_process_ppi_fps(uvc_camera_config->device);
564
565 err = bk_uvc_set_parameter((param >> 16), (param & 0xFFFF));
566 if (err != BK_OK)
567 {
568 UVC_LOGE("uvc set fps and ppi error!\r\n");
569 }
570
571 init_error:
572
573 return err;
574 }
575
uvc_camera_deinit(void)576 static bk_err_t uvc_camera_deinit(void)
577 {
578 // uvc deinit
579 bk_err_t status = 0;
580 g_uvc_start = 0;
581 rtos_delay_milliseconds(500);
582
583 if (uvc_camera_drv)
584 {
585 bk_dma_stop(uvc_camera_drv->uvc_dma);
586 bk_dma_deinit(uvc_camera_drv->uvc_dma);
587 bk_dma_free(DMA_DEV_USB, uvc_camera_drv->uvc_dma);
588
589 bk_dma_stop(uvc_camera_drv->psram_dma);
590 bk_dma_deinit(uvc_camera_drv->psram_dma);
591 bk_dma_free(DMA_DEV_DTCM, uvc_camera_drv->psram_dma);
592
593 if (uvc_camera_drv->buffer)
594 {
595 os_free(uvc_camera_drv->buffer);
596 uvc_camera_drv->buffer = NULL;
597 }
598
599 os_free(uvc_camera_drv);
600 uvc_camera_drv = NULL;
601 }
602
603 uvc_frame_id = 0;
604 uvc_camera_config = NULL;
605 curr_frame_buffer = NULL;
606 if (uvc_rx_vstream_buffptr)
607 {
608 os_free(uvc_rx_vstream_buffptr);
609 uvc_rx_vstream_buffptr = NULL;
610 }
611
612 UVC_LOGI("uvc_camera_deinit\n");
613
614 return status;
615 }
616
uvc_process_main(void)617 static void uvc_process_main(void)
618 {
619 bk_err_t err;
620
621 uvc_send_msg(UVC_START, 0);
622
623 while (1)
624 {
625 uvc_msg_t msg;
626 err = rtos_pop_from_queue(&uvc_drv_msg_que, &msg, BEKEN_WAIT_FOREVER);
627 if (kNoErr == err)
628 {
629 switch (msg.type)
630 {
631 case UVC_SET_PARAM:
632 uvc_set_ppi_fps(msg.data);
633 break;
634 case UVC_START:
635 uvc_set_start(msg.data);
636 break;
637 case UVC_STOP:
638 uvc_set_stop(msg.data);
639 break;
640 case UVC_EXIT:
641 goto uvc_exit;
642 break;
643 default:
644 break;
645 }
646 }
647 }
648
649 uvc_exit:
650
651 uvc_camera_deinit();
652
653 rtos_deinit_queue(&uvc_drv_msg_que);
654 uvc_drv_msg_que = NULL;
655
656 uvc_thread_drv_handle = NULL;
657 rtos_delete_thread(NULL);
658 }
659
bk_uvc_camera_power_on(void)660 bk_err_t bk_uvc_camera_power_on(void)
661 {
662 #if (CONFIG_DOORBELL_DEMO1)
663 BK_LOG_ON_ERR(bk_gpio_disable_input(37));
664 BK_LOG_ON_ERR(bk_gpio_enable_output(37));
665 // pull up gpio37, enable uvc camera vol
666 bk_gpio_set_output_low(37);
667 delay_ms(10);
668 bk_gpio_set_output_high(37);
669 #endif
670 return BK_OK;
671 }
672
bk_uvc_camera_get_config(uvc_camera_device_t * param,uint16_t count)673 bk_err_t bk_uvc_camera_get_config(uvc_camera_device_t *param, uint16_t count)
674 {
675 if (param == NULL)
676 {
677 return BK_FAIL;
678 }
679 bk_uvc_get_resolution_framerate((void *)param, count);
680
681 return BK_OK;
682 }
683
bk_uvc_camera_set_config(uvc_camera_device_t * config)684 bk_err_t bk_uvc_camera_set_config(uvc_camera_device_t *config)
685 {
686 int status = kNoErr;
687 uint32_t param = 0;
688 param = uvc_process_ppi_fps(config);
689
690 status = uvc_send_msg(UVC_SET_PARAM, param);
691
692 return status;
693 }
694
bk_uvc_camera_driver_start(void)695 bk_err_t bk_uvc_camera_driver_start(void)
696 {
697 uvc_send_msg(UVC_START, 0);
698
699 return BK_OK;
700 }
701
bk_uvc_camera_driver_stop(void)702 bk_err_t bk_uvc_camera_driver_stop(void)
703 {
704 uvc_send_msg(UVC_STOP, 0);
705
706 return BK_OK;
707 }
708
bk_uvc_camera_get_device(void)709 uvc_camera_device_t *bk_uvc_camera_get_device(void)
710 {
711 if (uvc_camera_config == NULL)
712 {
713 return NULL;
714 }
715
716 return uvc_camera_config->device;
717 }
718
bk_uvc_camera_driver_init(const uvc_camera_config_t * config)719 bk_err_t bk_uvc_camera_driver_init(const uvc_camera_config_t *config)
720 {
721 int ret = kNoErr;
722
723 BK_ASSERT(config->frame_alloc != NULL);
724 BK_ASSERT(config->frame_complete != NULL);
725
726 #if (CONFIG_PSRAM)
727 bk_psram_init();
728 #endif
729 if (uvc_camera_drv == NULL)
730 {
731 uvc_camera_drv = (uvc_camera_drv_t *)os_malloc(sizeof(uvc_camera_drv_t));
732
733 if (uvc_camera_drv == NULL)
734 {
735 UVC_LOGE("uvc_camera_drv malloc failed\n");
736 ret = kNoMemoryErr;
737 goto error;
738 }
739
740 os_memset(uvc_camera_drv, 0, sizeof(uvc_camera_drv));
741
742 uvc_camera_drv->buffer = (uint8 *)os_malloc(FRAME_BUFFER_UVC * 2);
743
744 if (uvc_camera_drv->buffer == NULL)
745 {
746 UVC_LOGE("uvc_camera_drv malloc failed\n");
747 if (uvc_camera_drv)
748 {
749 os_free(uvc_camera_drv);
750 uvc_camera_drv = NULL;
751 }
752
753 ret = kNoMemoryErr;
754 goto error;
755 }
756 }
757
758 uvc_camera_drv->rxbuf_len = FRAME_BUFFER_UVC * 2;
759 uvc_camera_drv->node_full_handler = uvc_process_data_packet;
760 uvc_camera_drv->frame_flag = 0x80;
761
762 uvc_camera_config = config;
763
764 if (uvc_camera_init(uvc_camera_config) != BK_OK)
765 {
766 ret = kGeneralErr;
767 goto error;
768 }
769
770 if ((!uvc_thread_drv_handle) && (!uvc_drv_msg_que))
771 {
772
773 ret = rtos_init_queue(&uvc_drv_msg_que,
774 "uvc_queue",
775 sizeof(uvc_msg_t),
776 30);
777 if (kNoErr != ret)
778 {
779 goto error;
780 }
781
782 ret = rtos_create_thread(&uvc_thread_drv_handle,
783 3,
784 "uvc_init",
785 (beken_thread_function_t)uvc_process_main,
786 4 * 1024,
787 (beken_thread_arg_t)0);
788
789 if (ret != kNoErr)
790 {
791
792 goto error;
793 }
794
795 return kNoErr;
796 }
797
798 error:
799
800 UVC_LOGI("uvc_camera_drv init failed\n");
801
802 if (uvc_camera_drv)
803 {
804 if (uvc_camera_drv->buffer)
805 {
806 os_free(uvc_camera_drv->buffer);
807 uvc_camera_drv->buffer = NULL;
808 }
809
810 os_free(uvc_camera_drv);
811 uvc_camera_drv = NULL;
812 }
813
814 uvc_camera_config = NULL;
815
816 uvc_camera_deinit();
817
818 if (uvc_drv_msg_que)
819 {
820 rtos_deinit_queue(&uvc_drv_msg_que);
821 uvc_drv_msg_que = NULL;
822 }
823
824 if (uvc_thread_drv_handle)
825 {
826 uvc_thread_drv_handle = NULL;
827 }
828
829 return ret;
830 }
831
bk_uvc_camera_driver_deinit(void)832 bk_err_t bk_uvc_camera_driver_deinit(void)
833 {
834 if (!uvc_thread_drv_handle)
835 {
836 return BK_OK;
837 }
838
839 uvc_send_msg(UVC_EXIT, 0);
840
841 while (uvc_thread_drv_handle)
842 {
843 rtos_delay_milliseconds(10);
844 }
845
846 return BK_OK;
847 }
848
849
850