py_camera.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #include <stdlib.h>
  2. #include "py/obj.h"
  3. #include "py/runtime.h"
  4. #include "py/mphal.h"
  5. #include "py/objarray.h"
  6. #include "py/binary.h"
  7. #ifdef EXTMODS_K210_DVP
  8. #include "py_img.h"
  9. typedef struct
  10. {
  11. mp_obj_base_t base;
  12. rt_dev_t sensor;
  13. void *dis;
  14. void *ai;
  15. int w;
  16. int h;
  17. }k210_cam_obj_t;
  18. volatile static uint32_t g_dvp_finish_flag;
  19. static rt_err_t camera_cb(rt_device_t dev, size_t size){
  20. g_dvp_finish_flag = 1;
  21. return RT_EOK;
  22. }
  23. static int k210sensor_reset(rt_dev_t *dev){
  24. if(*dev){
  25. rt_device_close(*dev);
  26. }
  27. *dev = rt_device_find("gc0308");
  28. if(rt_device_init(*dev) != RT_EOK){
  29. return -1;
  30. }
  31. if(rt_device_open(*dev,RT_DEVICE_OFLAG_RDWR) != RT_EOK){
  32. return -1;
  33. }
  34. rt_device_set_rx_indicate(*dev,camera_cb);
  35. return 0;
  36. }
  37. static int k210sensor_read(rt_dev_t *dev, uint8_t *dis, uint8_t *ai){
  38. if(!(*dev)){
  39. return -1;
  40. }
  41. g_dvp_finish_flag = 0;
  42. rt_device_read(*dev,0,dis,0);
  43. rt_tick_t start = rt_tick_get();
  44. while (g_dvp_finish_flag == 0)
  45. {
  46. usleep(100);
  47. if ((rt_tick_get() - start) > rt_tick_from_millisecond(1000)) //wait for 30ms
  48. return -1;
  49. }
  50. return 0;
  51. }
  52. const mp_obj_type_t k210_cam_type;
  53. STATIC mp_obj_t k210_cam_reset(mp_obj_t self)
  54. {
  55. k210_cam_obj_t *obj = (k210_cam_obj_t *)self;
  56. if (k210sensor_reset(&obj->sensor) != 0)
  57. {
  58. mp_raise_OSError(-1);
  59. }
  60. return mp_const_none;
  61. }
  62. STATIC MP_DEFINE_CONST_FUN_OBJ_1(k210_cam_reset_obj, k210_cam_reset);
  63. #if 0
  64. STATIC mp_obj_t k210_cam_set_pixformat(mp_obj_t self, mp_obj_t pixformat)
  65. {
  66. k210_cam_obj_t *obj = (k210_cam_obj_t *)self;
  67. if (k210sensor_set_pixformat(&obj->sensor, mp_obj_get_int(pixformat)) != 0)
  68. {
  69. mp_raise_OSError(-1);
  70. }
  71. return mp_const_none;
  72. }
  73. STATIC MP_DEFINE_CONST_FUN_OBJ_2(k210_cam_set_pixformat_obj, k210_cam_set_pixformat);
  74. #endif
  75. #if 1
  76. static mp_obj_t k210_cam_set_framesize(mp_obj_t self, mp_obj_t width, mp_obj_t height)
  77. {
  78. k210_cam_obj_t *obj = (k210_cam_obj_t *)self;
  79. int w, h, ow, oh;
  80. ow = obj->w;
  81. oh = obj->h;
  82. w = mp_obj_get_int(width);
  83. h = mp_obj_get_int(height);
  84. if ((w!=320) && (h!=240))
  85. {
  86. mp_raise_ValueError("invalid Width or Height, now only support 320x240");
  87. }
  88. obj->w = w;
  89. obj->h = h;
  90. // if (k210sensor_set_framesize(&obj->sensor, w, h) != 0)
  91. // {
  92. // mp_raise_OSError(-1);
  93. // }
  94. if ((w * h) != (ow * oh))
  95. {
  96. char *ptr;
  97. ptr = (char*)realloc(obj->dis, (w * h) * (2 + 3));
  98. if (!ptr)
  99. {
  100. mp_raise_msg_varg(&mp_type_MemoryError, MP_ERROR_TEXT("no memory"));
  101. }
  102. obj->dis = ptr;
  103. obj->ai = ptr + (w * h * 2);
  104. }
  105. return mp_const_none;
  106. }
  107. STATIC MP_DEFINE_CONST_FUN_OBJ_3(k210_cam_set_framesize_obj, k210_cam_set_framesize);
  108. #endif
  109. static mp_obj_t k210_cam_snapshot(mp_obj_t self)
  110. {
  111. k210_cam_obj_t *obj = (k210_cam_obj_t *)self;
  112. mp_obj_t dis_data, ai_data;
  113. rt_dev_t *s = &obj->sensor;
  114. int ret;
  115. if (!obj->dis)
  116. {
  117. mp_raise_ValueError("framebuffer not init");
  118. }
  119. dis_data = py_img(320, 240, PIXFORMAT_RGB565, 320*240*2, obj->dis);
  120. ai_data = py_img(320, 240, PIXFORMAT_RGB888_CHW, 320*240*3, obj->ai);
  121. ret = k210sensor_read(s, obj->dis, obj->ai);
  122. if (ret < 0)
  123. {
  124. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_RuntimeError, "Capture Failed: %d", ret));
  125. }
  126. mp_obj_list_t *ret_list = NULL;
  127. ret_list = m_new(mp_obj_list_t, 1);
  128. mp_obj_list_init(ret_list, 0);
  129. mp_obj_list_append(ret_list, dis_data );
  130. mp_obj_list_append(ret_list, ai_data );
  131. return MP_OBJ_FROM_PTR(ret_list);
  132. }
  133. STATIC MP_DEFINE_CONST_FUN_OBJ_1(k210_cam_snapshot_obj, k210_cam_snapshot);
  134. static mp_obj_t k210_cam_del(mp_obj_t self)
  135. {
  136. k210_cam_obj_t *obj = (k210_cam_obj_t *)self;
  137. if(!obj->sensor){
  138. rt_device_close(obj->sensor);
  139. obj->sensor = RT_NULL;
  140. }
  141. if (obj->dis)
  142. {
  143. realloc(obj->dis, 0);
  144. obj->dis = 0;
  145. obj->ai = 0;
  146. }
  147. return mp_const_none;
  148. }
  149. STATIC MP_DEFINE_CONST_FUN_OBJ_1(k210_cam_del_obj, k210_cam_del);
  150. STATIC mp_obj_t make_new()
  151. {
  152. k210_cam_obj_t *self = m_new_obj_with_finaliser(k210_cam_obj_t);
  153. self->base.type = &k210_cam_type;
  154. self->sensor = RT_NULL;
  155. return self;
  156. }
  157. #if 0
  158. static mp_obj_t k210_cam_switch(mp_obj_t self, mp_obj_t sel)
  159. {
  160. k210_cam_obj_t *obj = (k210_cam_obj_t *)self;
  161. k210sensor_t *s = &obj->sensor;
  162. if (mp_obj_get_type(sel) != &mp_type_int)
  163. mp_raise_ValueError("Invalid Value");
  164. int select = mp_obj_get_int(sel);
  165. if (select == 1)
  166. k210sensor_switch(s, 1);
  167. else if (select == 0)
  168. k210sensor_switch(s, 0);
  169. else
  170. mp_raise_ValueError("Invalid Value");
  171. return mp_const_none;
  172. }
  173. STATIC MP_DEFINE_CONST_FUN_OBJ_2(k210_cam_switch_obj, k210_cam_switch);
  174. #endif
  175. STATIC const mp_rom_map_elem_t locals_dict_table[] = {
  176. {MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&k210_cam_del_obj)},
  177. {MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&k210_cam_reset_obj)},
  178. // {MP_ROM_QSTR(MP_QSTR_set_pixformat), MP_ROM_PTR(&k210_cam_set_pixformat_obj)},
  179. {MP_ROM_QSTR(MP_QSTR_set_framesize), MP_ROM_PTR(&k210_cam_set_framesize_obj)},
  180. {MP_ROM_QSTR(MP_QSTR_snapshot), MP_ROM_PTR(&k210_cam_snapshot_obj)},
  181. // {MP_ROM_QSTR(MP_QSTR_sw), MP_ROM_PTR(&k210_cam_switch_obj)},
  182. // {MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(PIXFORMAT_RGB565)}, /* 2BPP/RGB565*/
  183. // {MP_ROM_QSTR(MP_QSTR_YUV422), MP_ROM_INT(PIXFORMAT_YUV422)}, /* 2BPP/YUV422*/
  184. };
  185. STATIC MP_DEFINE_CONST_DICT(k210_cam_dict, locals_dict_table);
  186. const mp_obj_type_t k210_cam_type = {
  187. .base = { &mp_type_type },
  188. .make_new = make_new,
  189. .name = MP_QSTR_camera,
  190. .locals_dict = (mp_obj_t)&k210_cam_dict,
  191. };
  192. #endif