CameraSensor_Mt9v117.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. #include <AP_HAL/AP_HAL.h>
  14. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
  15. #include "CameraSensor_Mt9v117.h"
  16. #include <utility>
  17. #include "GPIO.h"
  18. /* Cam sensor register definitions */
  19. #define CHIP_ID 0x0
  20. #define MT9V117_CHIP_ID 0x2282
  21. #define COMMAND_REGISTER 0x0040
  22. #define HOST_COMMAND_OK (1 << 15)
  23. #define HOST_COMMAND_2 (1 << 2)
  24. #define HOST_COMMAND_1 (1 << 1)
  25. #define HOST_COMMAND_0 (1 << 0)
  26. #define PAD_SLEW 0x0030
  27. #define RESET_AND_MISC_CONTROL 0x001a
  28. #define RESET_SOC_I2C (1 << 0)
  29. #define ACCESS_CTL_STAT 0x0982
  30. #define PHYSICAL_ADDRESS_ACCESS 0x098a
  31. #define LOGICAL_ADDRESS_ACCESS 0x098e
  32. #define AE_TRACK_JUMP_DIVISOR 0xa812
  33. #define CAM_AET_SKIP_FRAMES 0xc868
  34. #define AE_RULE_VAR 9
  35. #define AE_RULE_ALGO_OFFSET 4
  36. #define AE_RULE_ALGO_AVERAGE 0
  37. #define AE_RULE_ALGO_WEIGHTED 1
  38. #define AE_TRACK_VAR 10
  39. #define AWB_VAR 11
  40. #define AWB_PIXEL_THRESHOLD_COUNT_OFFSET 64
  41. #define LOW_LIGHT_VAR 15
  42. #define CAM_CTRL_VAR 18
  43. #define CAM_SENSOR_CFG_Y_ADDR_START_OFFSET 0
  44. #define CAM_SENSOR_CFG_X_ADDR_START_OFFSET 2
  45. #define CAM_SENSOR_CFG_Y_ADDR_END_OFFSET 4
  46. #define CAM_SENSOR_CFG_X_ADDR_END_OFFSET 6
  47. #define CAM_SENSOR_CFG_FRAME_LENGTH_LINES_OFFSET 14
  48. #define CAM_SENSOR_CFG_CPIPE_LAST_ROW_OFFSET 20
  49. #define CAM_SENSOR_CFG_FDPERIOD_60HZ 22
  50. #define CAM_SENSOR_CFG_FDPERIOD_50HZ 24
  51. #define CAM_SENSOR_CFG_MAX_FDZONE_60_OFFSET 26
  52. #define CAM_SENSOR_CFG_MAX_FDZONE_50_OFFSET 28
  53. #define CAM_SENSOR_CFG_TARGET_FDZONE_60_OFFSET 30
  54. #define CAM_SENSOR_CFG_TARGET_FDZONE_50_OFFSET 32
  55. #define CAM_SENSOR_CONTROL_READ_MODE_OFFSET 40
  56. #define CAM_SENSOR_CONTROL_Y_SKIP_EN (1 << 2)
  57. #define CAM_SENSOR_CONTROL_VERT_FLIP_EN (1 << 1)
  58. #define CAM_SENSOR_CONTROL_HORZ_MIRROR_EN (1 << 0)
  59. #define CAM_FLICKER_PERIOD_OFFSET 62
  60. #define CAM_FLICKER_PERIOD_60HZ 0
  61. #define CAM_FLICKER_PERIOD_50HZ 1
  62. #define CAM_CROP_WINDOW_XOFFSET_OFFSET 72
  63. #define CAM_CROP_WINDOW_YOFFSET_OFFSET 74
  64. #define CAM_CROP_WINDOW_WIDTH_OFFSET 76
  65. #define CAM_CROP_WINDOW_HEIGHT_OFFSET 78
  66. #define CAM_CROP_MODE_OFFSET 80
  67. #define CAM_OUTPUT_WIDTH_OFFSET 84
  68. #define CAM_OUTPUT_HEIGHT_OFFSET 86
  69. #define CAM_OUTPUT_FORMAT_OFFSET 88
  70. #define CAM_OUTPUT_FORMAT_RGB_565 (0 << 12)
  71. #define CAM_OUTPUT_FORMAT_RGB_555 (1 << 12)
  72. #define CAM_OUTPUT_FORMAT_RGB_444X (2 << 12)
  73. #define CAM_OUTPUT_FORMAT_RGB_X444 (3 << 12)
  74. #define CAM_OUTPUT_FORMAT_BAYER_10 (0 << 10)
  75. #define CAM_OUTPUT_FORMAT_YUV (0 << 8)
  76. #define CAM_OUTPUT_FORMAT_RGB (1 << 8)
  77. #define CAM_OUTPUT_FORMAT_BAYER (2 << 8)
  78. #define CAM_OUTPUT_FORMAT_BT656_ENABLE (1 << 3)
  79. #define CAM_OUTPUT_FORMAT_MONO_ENABLE (1 << 2)
  80. #define CAM_OUTPUT_FORMAT_SWAP_BYTES (1 << 1)
  81. #define CAM_OUTPUT_FORMAT_SWAP_RED_BLUE (1 << 0)
  82. #define CAM_STAT_AWB_HG_WINDOW_XSTART_OFFSET 236
  83. #define CAM_STAT_AWB_HG_WINDOW_YSTART_OFFSET 238
  84. #define CAM_STAT_AWB_HG_WINDOW_XEND_OFFSET 240
  85. #define CAM_STAT_AWB_HG_WINDOW_YEND_OFFSET 242
  86. #define CAM_STAT_AE_INITIAL_WINDOW_XSTART_OFFSET 244
  87. #define CAM_STAT_AE_INITIAL_WINDOW_YSTART_OFFSET 246
  88. #define CAM_STAT_AE_INITIAL_WINDOW_XEND_OFFSET 248
  89. #define CAM_STAT_AE_INITIAL_WINDOW_YEND_OFFSET 250
  90. #define CAM_LL_START_GAIN_METRIC_OFFSET 278
  91. #define CAM_LL_STOP_GAIN_METRIC_OFFSET 280
  92. #define SYSMGR_VAR 23
  93. #define SYSMGR_NEXT_STATE_OFFSET 0
  94. #define PATCHLDR_VAR 24
  95. #define PATCHLDR_LOADER_ADDRESS_OFFSET 0
  96. #define PATCHLDR_PATCH_ID_OFFSET 2
  97. #define PATCHLDR_FIRMWARE_ID_OFFSET 4
  98. extern const AP_HAL::HAL& hal;
  99. using namespace Linux;
  100. CameraSensor_Mt9v117::CameraSensor_Mt9v117(const char *device_path,
  101. AP_HAL::OwnPtr<AP_HAL::I2CDevice> dev,
  102. enum mt9v117_res res,
  103. uint16_t nrst_gpio, uint32_t clock_freq)
  104. : CameraSensor(device_path)
  105. , _dev(std::move(dev))
  106. , _nrst_gpio(nrst_gpio)
  107. , _clock_freq(clock_freq)
  108. {
  109. if (!_dev) {
  110. AP_HAL::panic("Could not find I2C bus for CameraSensor_Mt9v117");
  111. }
  112. switch (res) {
  113. case MT9V117_QVGA:
  114. _init_sensor();
  115. _configure_sensor_qvga();
  116. break;
  117. default:
  118. AP_HAL::panic("mt9v117: unsupported resolution\n");
  119. break;
  120. }
  121. _itu656_enable();
  122. _config_change();
  123. }
  124. uint8_t CameraSensor_Mt9v117::_read_reg8(uint16_t reg)
  125. {
  126. uint8_t buf[2];
  127. buf[0] = (uint8_t) (reg >> 8);
  128. buf[1] = (uint8_t) (reg & 0xFF);
  129. if (!_dev->transfer(buf, 2, buf, 1)) {
  130. hal.console->printf("mt9v117: error reading 0x%2x\n", reg);
  131. return 0;
  132. }
  133. return buf[0];
  134. }
  135. void CameraSensor_Mt9v117::_write_reg8(uint16_t reg, uint8_t val)
  136. {
  137. uint8_t buf[3];
  138. buf[0] = (uint8_t) (reg >> 8);
  139. buf[1] = (uint8_t) (reg & 0xFF);
  140. buf[2] = val;
  141. if (!_dev->transfer(buf, 3, nullptr, 0)) {
  142. hal.console->printf("mt9v117: error writing 0x%2x\n", reg);
  143. }
  144. }
  145. uint16_t CameraSensor_Mt9v117::_read_reg16(uint16_t reg)
  146. {
  147. uint8_t buf[2];
  148. buf[0] = (uint8_t) (reg >> 8);
  149. buf[1] = (uint8_t) (reg & 0xFF);
  150. if (!_dev->transfer(buf, 2, buf, 2)) {
  151. hal.console->printf("mt9v117: error reading 0x%4x\n", reg);
  152. return 0;
  153. }
  154. return (buf[0] << 8 | buf[1]);
  155. }
  156. void CameraSensor_Mt9v117::_write_reg16(uint16_t reg, uint16_t val)
  157. {
  158. uint8_t buf[4];
  159. buf[0] = (uint8_t) (reg >> 8);
  160. buf[1] = (uint8_t) (reg & 0xFF);
  161. buf[2] = (uint8_t) (val >> 8);
  162. buf[3] = (uint8_t) (val & 0xFF);
  163. if (!_dev->transfer(buf, 4, nullptr, 0)) {
  164. hal.console->printf("mt9v117: error writing 0x%4x\n", reg);
  165. }
  166. }
  167. void CameraSensor_Mt9v117::_write_reg32(uint16_t reg, uint32_t val)
  168. {
  169. uint8_t buf[6];
  170. buf[0] = (uint8_t) (reg >> 8);
  171. buf[1] = (uint8_t) (reg & 0xFF);
  172. buf[2] = (uint8_t) (val >> 24);
  173. buf[3] = (uint8_t) ((val >> 16) & 0xFF);
  174. buf[4] = (uint8_t) ((val >> 8) & 0xFF);
  175. buf[5] = (uint8_t) (val & 0xFF);
  176. if (!_dev->transfer(buf, 6, nullptr, 0)) {
  177. hal.console->printf("mt9v117: error writing 0x%8x\n", reg);
  178. }
  179. }
  180. inline uint16_t CameraSensor_Mt9v117::_var2reg(uint16_t var,
  181. uint16_t offset)
  182. {
  183. return (0x8000 | (var << 10) | offset);
  184. }
  185. uint16_t CameraSensor_Mt9v117::_read_var16(uint16_t var, uint16_t offset)
  186. {
  187. uint16_t reg = _var2reg(var, offset);
  188. return _read_reg16(reg);
  189. }
  190. void CameraSensor_Mt9v117::_write_var16(uint16_t var,
  191. uint16_t offset,
  192. uint16_t value)
  193. {
  194. uint16_t reg = _var2reg(var, offset);
  195. _write_reg16(reg, value);
  196. }
  197. uint8_t CameraSensor_Mt9v117::_read_var8(uint16_t var, uint16_t offset)
  198. {
  199. uint16_t reg = _var2reg(var, offset);
  200. return _read_reg8(reg);
  201. }
  202. void CameraSensor_Mt9v117::_write_var8(uint16_t var,
  203. uint16_t offset,
  204. uint8_t value)
  205. {
  206. uint16_t reg = _var2reg(var, offset);
  207. return _write_reg8(reg, value);
  208. }
  209. void CameraSensor_Mt9v117::_write_var32(uint16_t var,
  210. uint16_t offset,
  211. uint32_t value)
  212. {
  213. uint16_t reg = _var2reg(var, offset);
  214. return _write_reg32(reg, value);
  215. }
  216. void CameraSensor_Mt9v117::_config_change()
  217. {
  218. uint16_t cmd_status;
  219. /* timeout 100ms delay 10ms */
  220. int timeout = 10;
  221. _write_var8(SYSMGR_VAR, SYSMGR_NEXT_STATE_OFFSET, 0x28);
  222. _write_reg16(COMMAND_REGISTER, HOST_COMMAND_OK | HOST_COMMAND_1);
  223. do {
  224. hal.scheduler->delay(10);
  225. cmd_status = _read_reg16(COMMAND_REGISTER);
  226. timeout--;
  227. } while (((cmd_status & HOST_COMMAND_1) != 0) &&
  228. (timeout > 0));
  229. if (timeout == 0) {
  230. hal.console->printf("mt9v117:"
  231. "timeout waiting or command to complete\n");
  232. }
  233. if ((cmd_status & HOST_COMMAND_OK) == 0) {
  234. hal.console->printf("mt9v117:config change failed\n");
  235. }
  236. }
  237. void CameraSensor_Mt9v117::_itu656_enable()
  238. {
  239. _write_var16(CAM_CTRL_VAR, CAM_OUTPUT_FORMAT_OFFSET,
  240. _read_var16(CAM_CTRL_VAR, CAM_OUTPUT_FORMAT_OFFSET) |
  241. CAM_OUTPUT_FORMAT_BT656_ENABLE);
  242. }
  243. void CameraSensor_Mt9v117::_soft_reset()
  244. {
  245. _write_reg16(RESET_AND_MISC_CONTROL, RESET_SOC_I2C);
  246. _write_reg16(RESET_AND_MISC_CONTROL, 0);
  247. /* sleep 50ms after soft reset */
  248. hal.scheduler->delay(50);
  249. }
  250. void CameraSensor_Mt9v117::_apply_patch()
  251. {
  252. uint16_t cmd_status;
  253. /* timeout 100ms delay 10ms */
  254. int timeout = 10;
  255. /* Errata item 2 */
  256. _write_reg16(0x301a, 0x10d0);
  257. _write_reg16(0x31c0, 0x1404);
  258. _write_reg16(0x3ed8, 0x879c);
  259. _write_reg16(0x3042, 0x20e1);
  260. _write_reg16(0x30d4, 0x8020);
  261. _write_reg16(0x30c0, 0x0026);
  262. _write_reg16(0x301a, 0x10d4);
  263. /* Errata item 6 */
  264. _write_var16(AE_TRACK_VAR, 0x0002, 0x00d3);
  265. _write_var16(CAM_CTRL_VAR, 0x0078, 0x00a0);
  266. _write_var16(CAM_CTRL_VAR, 0x0076, 0x0140);
  267. /* Errata item 8 */
  268. _write_var16(LOW_LIGHT_VAR, 0x0004, 0x00fc);
  269. _write_var16(LOW_LIGHT_VAR, 0x0038, 0x007f);
  270. _write_var16(LOW_LIGHT_VAR, 0x003a, 0x007f);
  271. _write_var16(LOW_LIGHT_VAR, 0x003c, 0x007f);
  272. _write_var16(LOW_LIGHT_VAR, 0x0004, 0x00f4);
  273. /* Patch 0403; Critical; Sensor optimization */
  274. _write_reg16(ACCESS_CTL_STAT, 0x0001);
  275. _write_reg16(PHYSICAL_ADDRESS_ACCESS, 0x7000);
  276. /* write patch */
  277. for (unsigned int i = 0; i < MT9V117_PATCH_LINE_NUM; i++) {
  278. _dev->transfer(_patch_lines[i].data, _patch_lines[i].size, nullptr, 0);
  279. }
  280. _write_reg16(LOGICAL_ADDRESS_ACCESS, 0x0000);
  281. _write_var16(PATCHLDR_VAR, PATCHLDR_LOADER_ADDRESS_OFFSET, 0x05d8);
  282. _write_var16(PATCHLDR_VAR, PATCHLDR_PATCH_ID_OFFSET, 0x0403);
  283. _write_var32(PATCHLDR_VAR, PATCHLDR_FIRMWARE_ID_OFFSET, 0x00430104);
  284. _write_reg16(COMMAND_REGISTER, HOST_COMMAND_OK | HOST_COMMAND_0);
  285. do {
  286. hal.scheduler->delay(10);
  287. cmd_status = _read_reg16(COMMAND_REGISTER);
  288. timeout--;
  289. } while (((cmd_status & HOST_COMMAND_0) != 0) &&
  290. (timeout > 0));
  291. if ((cmd_status & HOST_COMMAND_OK) == 0) {
  292. hal.console->printf("mt9v117:patch apply failed\n");
  293. }
  294. }
  295. void CameraSensor_Mt9v117::_set_basic_settings()
  296. {
  297. _write_var32(AWB_VAR, AWB_PIXEL_THRESHOLD_COUNT_OFFSET, 50000);
  298. _write_var16(AE_RULE_VAR, AE_RULE_ALGO_OFFSET, AE_RULE_ALGO_AVERAGE);
  299. /* Set pixclk pad slew to 6 and data out pad slew to 1 */
  300. _write_reg16(PAD_SLEW, _read_reg16(PAD_SLEW) | 0x0600 | 0x0001);
  301. }
  302. void CameraSensor_Mt9v117::_configure_sensor_qvga()
  303. {
  304. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CFG_X_ADDR_START_OFFSET, 16);
  305. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CFG_X_ADDR_END_OFFSET, 663);
  306. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CFG_Y_ADDR_START_OFFSET, 8);
  307. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CFG_Y_ADDR_END_OFFSET, 501);
  308. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CFG_CPIPE_LAST_ROW_OFFSET, 243);
  309. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CFG_FRAME_LENGTH_LINES_OFFSET, 283);
  310. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CONTROL_READ_MODE_OFFSET,
  311. CAM_SENSOR_CONTROL_Y_SKIP_EN);
  312. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CFG_MAX_FDZONE_60_OFFSET, 1);
  313. _write_var16(CAM_CTRL_VAR, CAM_SENSOR_CFG_TARGET_FDZONE_60_OFFSET, 1);
  314. _write_reg8(AE_TRACK_JUMP_DIVISOR, 0x03);
  315. _write_reg8(CAM_AET_SKIP_FRAMES, 0x02);
  316. _write_var16(CAM_CTRL_VAR, CAM_OUTPUT_WIDTH_OFFSET, 320);
  317. _write_var16(CAM_CTRL_VAR, CAM_OUTPUT_HEIGHT_OFFSET, 240);
  318. /* Set gain metric for 111.2 fps
  319. * The final fps depends on the input clock
  320. * (89.2fps on bebop) so a modification may be needed here */
  321. _write_var16(CAM_CTRL_VAR, CAM_LL_START_GAIN_METRIC_OFFSET, 0x03e8);
  322. _write_var16(CAM_CTRL_VAR, CAM_LL_STOP_GAIN_METRIC_OFFSET, 0x1770);
  323. /* set crop window */
  324. _write_var16(CAM_CTRL_VAR, CAM_CROP_WINDOW_XOFFSET_OFFSET, 0);
  325. _write_var16(CAM_CTRL_VAR, CAM_CROP_WINDOW_YOFFSET_OFFSET, 0);
  326. _write_var16(CAM_CTRL_VAR, CAM_CROP_WINDOW_WIDTH_OFFSET, 640);
  327. _write_var16(CAM_CTRL_VAR, CAM_CROP_WINDOW_HEIGHT_OFFSET, 240);
  328. /* Enable auto-stats mode */
  329. _write_var8(CAM_CTRL_VAR, CAM_CROP_MODE_OFFSET, 3);
  330. _write_var16(CAM_CTRL_VAR, CAM_STAT_AWB_HG_WINDOW_XEND_OFFSET, 319);
  331. _write_var16(CAM_CTRL_VAR, CAM_STAT_AWB_HG_WINDOW_YEND_OFFSET, 239);
  332. _write_var16(CAM_CTRL_VAR, CAM_STAT_AE_INITIAL_WINDOW_XSTART_OFFSET, 2);
  333. _write_var16(CAM_CTRL_VAR, CAM_STAT_AE_INITIAL_WINDOW_YSTART_OFFSET, 2);
  334. _write_var16(CAM_CTRL_VAR, CAM_STAT_AE_INITIAL_WINDOW_XEND_OFFSET, 65);
  335. _write_var16(CAM_CTRL_VAR, CAM_STAT_AE_INITIAL_WINDOW_YEND_OFFSET, 49);
  336. }
  337. void CameraSensor_Mt9v117::_init_sensor()
  338. {
  339. AP_HAL::DigitalSource *gpio_source;
  340. uint16_t id;
  341. if (_nrst_gpio != 0xFFFF) {
  342. gpio_source = hal.gpio->channel(_nrst_gpio);
  343. gpio_source->mode(HAL_GPIO_OUTPUT);
  344. gpio_source->write(1);
  345. uint32_t delay = 3.5f + (35.0f - 3.5f) *
  346. (54000000.0f - (float)_clock_freq) /
  347. (54000000.0f - 6000000.0f);
  348. hal.scheduler->delay(delay);
  349. }
  350. id = _read_reg16(CHIP_ID);
  351. if (id != MT9V117_CHIP_ID) {
  352. AP_HAL::panic("Mt9v117: bad chip id 0x%04x\n", id);
  353. }
  354. _soft_reset();
  355. _apply_patch();
  356. _set_basic_settings();
  357. }
  358. #endif