• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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