pxp.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. #include "FreeRTOS.h"
  2. #include "board.h"
  3. #include "chip.h"
  4. #ifndef abs
  5. #define abs(a, b) ((a > b) ? (a - b) : (b - a))
  6. #endif
  7. static SemaphoreHandle_t pxp_mutex = NULL;
  8. static QueueHandle_t pxp_done;
  9. struct ark_pxp_data
  10. {
  11. pxp_param param;
  12. uint32_t block_size;
  13. };
  14. struct ark_pxp_data *g_pxp = NULL;
  15. static int pxp_set_bits(uint32_t reg, uint32_t mask, uint32_t offset, uint32_t val)
  16. {
  17. uint32_t tmp = PXP_READL(reg);
  18. tmp &= (~(mask << offset));
  19. tmp |= ((val&mask) << offset);
  20. PXP_WRITEL(tmp, reg);
  21. return 0;
  22. }
  23. /*
  24. * PXP Overlay Functions
  25. */
  26. int pxp_overlay_set_addr(PXP_OL_LAYER layer, uint32_t addr)
  27. {
  28. uint32_t reg = PXP_OL0BUF + layer*0x40;
  29. if(layer >= PXP_OL_COUNT) {
  30. printf("ERR: Invalid layer:%d\n", layer);
  31. return -1;
  32. }
  33. PXP_WRITEL(addr, reg);
  34. return 0;
  35. }
  36. int pxp_get_block_size(void)
  37. {
  38. #if 0
  39. if(PXP_READL(PXP_CTRL) & (1<<23))
  40. return PXP_BLOCK_SIZE_16X16;
  41. return PXP_BLOCK_SIZE_8X8;
  42. #else
  43. if(g_pxp)
  44. return g_pxp->block_size;
  45. return (PXP_READL(PXP_CTRL)>>23)&0x1;
  46. #endif
  47. }
  48. int pxp_overlay_set_size(PXP_OL_LAYER layer, uint32_t xbase, uint32_t ybase, uint32_t width, uint32_t height)
  49. {
  50. uint32_t reg = PXP_OL0SIZE + layer*0x40;
  51. uint32_t block_size;
  52. uint32_t div;
  53. if(layer >= PXP_OL_COUNT) {
  54. printf("ERR: Invalid layer:%d\n", layer);
  55. return -1;
  56. }
  57. block_size = pxp_get_block_size();
  58. if(block_size == PXP_BLOCK_SIZE_8X8) {
  59. div = 8;
  60. } else if(block_size == PXP_BLOCK_SIZE_16X16) {
  61. div = 16;
  62. }
  63. xbase /= div; //x_blocks = x_pixel /block_size;
  64. ybase /= div; //
  65. width /= div; //w_blocks = w_pixel /block_size;
  66. height /= div; //
  67. if((xbase > 0xFF) || (ybase > 0xFF) || (width > 0xFF) || (height > 0xFF)) {
  68. printf("ERR: Invalid overlay:%d xbase:%d, ybase:%d, width:%d or height:%d\n",
  69. xbase, ybase, layer, width, height);
  70. return -1;
  71. }
  72. PXP_WRITEL((xbase<<24)|(ybase<<16)|(width<<8)|height, reg);
  73. return 0;
  74. }
  75. int pxp_overlay_set_rop(PXP_OL_LAYER layer, uint32_t rop)
  76. {
  77. uint32_t reg = PXP_OL0PARAM + layer*0x40;
  78. if(layer >= PXP_OL_COUNT) {
  79. printf("ERR: Invalid layer:%d\n", layer);
  80. return -1;
  81. }
  82. if(rop > 0xF) {
  83. printf("ERR: Invalid overlay%d rop:%d\n", layer, rop);
  84. return -1;
  85. }
  86. return pxp_set_bits(reg, 0xF, 16, rop);
  87. }
  88. int pxp_overlay_set_format(PXP_OL_LAYER layer, PXP_OL_FORMAT format)
  89. {
  90. uint32_t reg = PXP_OL0PARAM + layer*0x40;
  91. if(layer >= PXP_OL_COUNT) {
  92. printf("ERR: Invalid layer:%d\n", layer);
  93. return -1;
  94. }
  95. if(format >= PXP_OL_FORMAT_END) {
  96. printf("ERR: Invalid format:%d\n", format);
  97. return -1;
  98. }
  99. return pxp_set_bits(reg, 0xF, 4, format);
  100. }
  101. int pxp_overlay_set_alpha_value(PXP_OL_LAYER layer, uint32_t value)
  102. {
  103. uint32_t reg = PXP_OL0PARAM + layer*0x40;
  104. if(layer >= PXP_OL_COUNT) {
  105. printf("ERR: Invalid layer:%d\n", layer);
  106. return -1;
  107. }
  108. if(value > 0xFF) {
  109. printf("ERR: Invalid alpha value:%d\n", value);
  110. return -1;
  111. }
  112. return pxp_set_bits(reg, 0xFF, 8, value);
  113. }
  114. int pxp_overlay_set_alpha_cntl_type(PXP_OL_LAYER layer, PXP_OL_ALPHA_CNTL_TYPE type)
  115. {
  116. uint32_t reg = PXP_OL0PARAM + layer*0x40;
  117. if(layer >= PXP_OL_COUNT) {
  118. printf("ERR: Invalid layer:%d\n", layer);
  119. return -1;
  120. }
  121. if(type >= PXP_OL_ALPHA_CNTL_TYPE_END) {
  122. printf("ERR: Invalid alpha cntl type:%d\n", type);
  123. return -1;
  124. }
  125. return pxp_set_bits(reg, 0x3, 1, type);
  126. }
  127. int pxp_overlay_colorkey_enable(PXP_OL_LAYER layer, uint32_t enable)
  128. {
  129. uint32_t reg = PXP_OL0PARAM + layer*0x40;
  130. if(layer >= PXP_OL_COUNT) {
  131. printf("ERR: Invalid layer:%d\n", layer);
  132. return -1;
  133. }
  134. return pxp_set_bits(reg, 0x1, 3, (enable?1:0));
  135. }
  136. int pxp_set_overlay_color_key(uint32_t low, uint32_t high)
  137. {
  138. if((low > 0xFFFFFF) || (high > 0xFFFFFF)) {
  139. printf("ERR: Invalid low(%d) or high(%d)\n", low, high);
  140. return -1;
  141. }
  142. PXP_WRITEL(low, PXP_OLCKEYL);
  143. PXP_WRITEL(high, PXP_OLCKEYH);
  144. return 0;
  145. }
  146. int pxp_overlay_enable(PXP_OL_LAYER layer, uint32_t enable)
  147. {
  148. uint32_t reg = PXP_OL0PARAM + layer*0x40;
  149. if(layer >= PXP_OL_COUNT) {
  150. printf("ERR: Invalid layer:%d\n", layer);
  151. return -1;
  152. }
  153. return pxp_set_bits(reg, 0x1, 0, (enable?1:0));
  154. }
  155. /*
  156. * PXP Common Functions
  157. */
  158. static int pxp_set_out_buf(uint32_t addr)
  159. {
  160. PXP_WRITEL(addr, PXP_OUTBUF);
  161. return 0;
  162. }
  163. static int pxp_set_out_buf2(uint32_t addr)
  164. {
  165. PXP_WRITEL(addr, PXP_OUTBUF2);
  166. return 0;
  167. }
  168. int pxp_set_output_size(uint32_t width, uint32_t height)
  169. {
  170. if((width > 0xFFF) || ((height > 0xFFF))) {
  171. printf("ERR: Invalid width:%d or height:%d\n", width, height);
  172. return -1;
  173. }
  174. return pxp_set_bits(PXP_OUTSIZE, 0xFFFFFF, 0, (width<<12)|height);
  175. }
  176. static int pxp_set_s0_input_yaddr(uint32_t addr)
  177. {
  178. PXP_WRITEL(addr, PXP_S0BUF);
  179. return 0;
  180. }
  181. static int pxp_set_s0_input_uaddr(uint32_t addr)
  182. {
  183. PXP_WRITEL(addr, PXP_S0UBUF);
  184. return 0;
  185. }
  186. static int pxp_set_s0_input_vaddr(uint32_t addr)
  187. {
  188. PXP_WRITEL(addr, PXP_S0VBUF);
  189. return 0;
  190. }
  191. int pxp_set_s0_input_size(uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height)
  192. {
  193. uint32_t block_size;
  194. uint32_t in_xbase = xoffset;
  195. uint32_t in_ybase = yoffset;
  196. uint32_t in_width = width;
  197. uint32_t in_height = height;
  198. uint32_t div;
  199. block_size = pxp_get_block_size();
  200. if(block_size == PXP_BLOCK_SIZE_8X8) {
  201. div = 8;
  202. } else if(block_size == PXP_BLOCK_SIZE_16X16) {
  203. div = 16;
  204. }
  205. xoffset /= div; //x_block = x_pixel /block_size;
  206. yoffset /= div; //
  207. width /= div; //w_block = w_pixel /block_size;
  208. height /= div; //
  209. if((xoffset > 0xFF) || (yoffset > 0xFF) || (width > 0xFF) || (height > 0xFF)) {
  210. printf("ERR: Invalid xoffset:%d or yoffset:%d, or width:%d or height:%d\n",
  211. in_xbase, in_ybase, in_width, in_height);
  212. return -1;
  213. }
  214. PXP_WRITEL((xoffset<<24)|(yoffset<<16)|(width<<8)|height, PXP_S0PARAM);
  215. return 0;
  216. }
  217. int pxp_set_s0_cropping_size(uint32_t xbase, uint32_t ybase, uint32_t width, uint32_t height)
  218. {
  219. uint32_t block_size;
  220. uint32_t div;
  221. block_size = pxp_get_block_size();
  222. if(block_size == PXP_BLOCK_SIZE_8X8) {
  223. div = 8;
  224. } else if(block_size == PXP_BLOCK_SIZE_16X16) {
  225. div = 16;
  226. }
  227. xbase /= div; //x_blocks = x_pixel /block_size;
  228. ybase /= div; //
  229. width /= div; //w_blocks = w_pixel /block_size;
  230. height /= div; //
  231. if((xbase > 0xFF) || (ybase > 0xFF) || (width > 0xFF) || (height > 0xFF)) {
  232. printf("ERR: Invalid xbase:%d or ybase:%d, or width:%d or height:%d\n",
  233. xbase*div, ybase*div, width*div, height*div);
  234. return -1;
  235. }
  236. PXP_WRITEL((xbase<<24)|(ybase<<16)|(width<<8)|height, PXP_S0CROP);
  237. return 0;
  238. }
  239. int pxp_set_s0_scale_factor(uint32_t xscale, uint32_t yscale)
  240. {
  241. if((xscale >= 0x7FFF) || (yscale >= 0x7FFF)) {
  242. printf("ERR: Invalid scale_factor xscale:%d or yscale:%d\n", xscale, yscale);
  243. return -1;
  244. }
  245. PXP_WRITEL((yscale<<16)|xscale, PXP_S0SCALE);
  246. return 0;
  247. }
  248. /*
  249. * PXP Global Functions
  250. */
  251. int pxp_set_s0_scale_offset(uint32_t x, uint32_t y)
  252. {
  253. if((x >= 0xFFF) || (y >= 0xFFF)) {
  254. printf("ERR: Invalid x:%d or y:%d\n", x, y);
  255. return -1;
  256. }
  257. PXP_WRITEL((y<<16)|x, PXP_S0OFFSET);
  258. return 0;
  259. }
  260. int pxp_set_color_space_conversion_coefficient(PXP_CSCOEFF mode)
  261. {
  262. if(mode >= PCP_CSCCOEFF_END) {
  263. printf("ERR: Invalid mode:%d\n", mode);
  264. return -1;
  265. }
  266. if(mode == PXP_CSCCOEFF_YUV2RGB) {
  267. PXP_WRITEL((0x0<<31)|(0x100<<18)|(0x0<<9)|(0x0<<0), PXP_CSCCOEFF0);
  268. PXP_WRITEL((0x123<<16)|(0x208<<0), PXP_CSCCOEFF1);
  269. PXP_WRITEL((0x76B<<16)|(0x76C<<0), PXP_CSCCOEFF2);
  270. } else if(mode == PXP_CSCCOEFF_YCBCR2RGB) {
  271. PXP_WRITEL((0x1<<31)|(0x12A<<18)|(0x180<<9)|(0x1F0<<0), PXP_CSCCOEFF0);
  272. PXP_WRITEL((0x198<<16)|(0x204<<0), PXP_CSCCOEFF1);
  273. PXP_WRITEL((0x730<<16)|(0x79C<<0), PXP_CSCCOEFF2);
  274. }
  275. return 0;
  276. }
  277. int pxp_set_block_size(PXP_BLOCK_SIZE_TYPE type)
  278. {
  279. int ret;
  280. if(!g_pxp) {
  281. printf("ERR: Invalid g_pxp(NULL)\n");
  282. return -1;
  283. }
  284. if(type >= PXP_BLOCK_SIZE_END) {
  285. type = PXP_BLOCK_SIZE_8X8;
  286. printf("ERR: Invalid type:%d, using default block size(8x8)\n", type);
  287. }
  288. g_pxp->block_size = type;
  289. ret = pxp_set_bits(PXP_CTRL, 0x1, 23, type);
  290. return ret;
  291. }
  292. int pxp_set_output_alpha(uint32_t alpha)
  293. {
  294. if(alpha > 0xFF) {
  295. printf("ERR: Invalid alpha:%d\n", alpha);
  296. return -1;
  297. }
  298. return pxp_set_bits(PXP_OUTSIZE, 0xFF, 24, alpha);
  299. }
  300. int pxp_set_s0_background_color(uint32_t color)
  301. {
  302. PXP_WRITEL(color, PXP_S0BACKGROUND);
  303. return 0;
  304. }
  305. int pxp_set_s0_color_key(uint32_t low, uint32_t high)
  306. {
  307. if((low > 0xFFFFFF) || (high > 0xFFFFFF)) {
  308. printf("ERR: Invalid low(%d) or high(%d)\n", low, high);
  309. return -1;
  310. }
  311. PXP_WRITEL(low, PXP_S0CKEYL);
  312. PXP_WRITEL(high, PXP_S0CKEYH);
  313. return 0;
  314. }
  315. int pxp_set_input_addr(uint32_t yaddr, uint32_t uaddr, uint32_t vaddr)
  316. {
  317. struct ark_pxp_data *pxp = g_pxp;
  318. if(!pxp) {
  319. printf("ERR: Invalid g_pxp(NULL)\n");
  320. return -1;
  321. }
  322. if(!yaddr) {
  323. printf("ERR: Invalid yaddr(0)\n");
  324. return -1;
  325. }
  326. pxp_set_s0_input_yaddr(yaddr);
  327. pxp_set_s0_input_uaddr(uaddr);
  328. pxp_set_s0_input_vaddr(vaddr);
  329. return 0;
  330. }
  331. int pxp_set_output_addr(uint32_t addr, uint32_t addr2)
  332. {
  333. struct ark_pxp_data *pxp = g_pxp;
  334. if(!pxp) {
  335. printf("ERR: Invalid g_pxp(NULL)\n");
  336. return -1;
  337. }
  338. if(!addr) {
  339. printf("ERR: Invalid yaddr(0)\n");
  340. return -1;
  341. }
  342. pxp_set_out_buf(addr);
  343. pxp_set_out_buf2(addr2);
  344. return 0;
  345. }
  346. int pxp_set_control_param(pxp_param *param)
  347. {
  348. struct ark_pxp_data *pxp = g_pxp;
  349. if(!pxp || !param) {
  350. printf("ERR: Invalid pxp(%p) or param(%p)\n", pxp, param);
  351. return -1;
  352. }
  353. memcpy(&pxp->param, param, sizeof(pxp_param));
  354. return 0;
  355. }
  356. int pxp_reset(void)
  357. {
  358. PXP_WRITEL(1 << 31, PXP_CTRL);
  359. udelay(10);
  360. PXP_WRITEL(0, PXP_CTRL);
  361. return 0;
  362. }
  363. int pxp_start(void)
  364. {
  365. struct ark_pxp_data *pxp = g_pxp;
  366. pxp_param *param = NULL;
  367. PXP_BLOCK_SIZE_TYPE block_size = PXP_BLOCK_SIZE_8X8;
  368. if(!pxp) {
  369. printf("ERR: Invalid pxp(%p)\n", pxp);
  370. return -1;
  371. }
  372. param = &pxp->param;
  373. block_size = pxp->block_size;
  374. PXP_WRITEL(
  375. (0<<SFTRST) |
  376. (0<<CLKGATE) |
  377. ((param->out_interlace_enable)<<INTERLACED_OUTPUT) |
  378. ((param->in_interlace_enable)<<INTERLACED_INPUT) |
  379. ((block_size)<<BLOCK_SIZE) |
  380. ((param->alpha_out_enable)<<ALPHA_OUTPUT) |
  381. ((param->in_place)<<IN_PLACE) |
  382. ((param->crop_enable)<<CROP) |
  383. ((param->scale_enable)<<SCALE) |
  384. ((param->in_format&0xF)<<S0_FORMAT) |
  385. ((param->vflip_enable)<<VFLIP) |
  386. ((param->hflip_enable)<<HFLIP) |
  387. ((param->rotate&0x3)<<ROTATE) |
  388. ((param->out_format&0xF)<<OUTBUF_FORMAT) |
  389. (0<<LCD_HANDSHAKE_EN) |
  390. (0<<NEXT_IRQ_EN) |
  391. (1<<IRQ_EN) |
  392. (1<<PXP_EN)
  393. , PXP_CTRL);
  394. return 0;
  395. }
  396. /* this function can not used in isr */
  397. int pxp_scaler_rotate(uint32_t s0buf, uint32_t s0ubuf, uint32_t s0vbuf,
  398. int s0format, uint32_t s0width, uint32_t s0height,
  399. uint32_t outbuf, uint32_t outbuf2, int outformat,
  400. uint32_t outwidth, uint32_t outheight, int outangle)
  401. {
  402. uint32_t ctrl;
  403. int ret = 0;
  404. int cutx = 0;
  405. int cuty = 0;
  406. configASSERT(outangle >= PXP_ROTATE_0 && outangle <= PXP_ROTATE_270 && g_pxp);
  407. if(abs(s0width, outwidth) < 16)
  408. cutx = 0;
  409. if(abs(s0height, outheight) < 16)
  410. cutx = 0;
  411. if (outangle == PXP_ROTATE_90 || outangle == PXP_ROTATE_270) {
  412. uint32_t tmp = outheight;
  413. outheight = outwidth;
  414. outwidth = tmp;
  415. }
  416. xSemaphoreTake(pxp_mutex, portMAX_DELAY);
  417. pxp_reset();
  418. pxp_set_block_size(PXP_BLOCK_SIZE_8X8);
  419. pxp_set_output_addr(outbuf, outbuf2);
  420. pxp_set_output_size(outwidth, outheight);
  421. pxp_set_output_alpha(0xff);
  422. pxp_set_input_addr(s0buf, s0ubuf, s0vbuf);
  423. pxp_set_s0_input_size(0, 0, s0width, s0height);
  424. pxp_set_s0_background_color(0);
  425. pxp_set_s0_cropping_size(0, 0, outwidth, outheight);
  426. pxp_set_s0_scale_factor(s0width * 0x1000 / (outwidth + cutx), s0height * 0x1000 / (outheight + cuty));
  427. pxp_set_color_space_conversion_coefficient(PXP_CSCCOEFF_YCBCR2RGB);
  428. pxp_param param;
  429. memset(&param, 0, sizeof(pxp_param));
  430. param.in_format = s0format;
  431. param.out_format = outformat;
  432. param.in_interlace_enable = 0;
  433. param.out_interlace_enable = 0;
  434. param.rotate = outangle;
  435. param.vflip_enable = 0;
  436. #ifdef PXP_OUTPUT_MIRROR
  437. param.hflip_enable = 1;
  438. #endif
  439. param.crop_enable = 1;
  440. param.scale_enable = 1;
  441. if(outformat == PXP_OUT_FORMAT_ARGB888)
  442. param.alpha_out_enable = 1;
  443. pxp_set_control_param(&param);
  444. xQueueReset(pxp_done);
  445. pxp_start();
  446. if (xQueueReceive(pxp_done, NULL, pdMS_TO_TICKS(1000)) != pdTRUE) {
  447. printf("pxp timeout.\n");
  448. ret = -ETIMEDOUT;
  449. }
  450. xSemaphoreGive(pxp_mutex);
  451. return ret;
  452. }
  453. int pxp_rotate(uint32_t s0buf, uint32_t s0ubuf, uint32_t s0vbuf,
  454. int s0format, uint32_t s0width, uint32_t s0height,
  455. uint32_t outbuf, uint32_t outbuf2, int outformat,
  456. int outangle)
  457. {
  458. uint32_t ctrl;
  459. int ret = 0;
  460. int alpha_out_enable = 0;
  461. int crop_enable = 0;
  462. configASSERT(outangle >= PXP_ROTATE_0 && outangle <= PXP_ROTATE_270);
  463. xSemaphoreTake(pxp_mutex, portMAX_DELAY);
  464. pxp_reset();
  465. pxp_set_block_size(PXP_BLOCK_SIZE_8X8);
  466. pxp_set_output_addr(outbuf, outbuf2);
  467. pxp_set_output_size(s0width, s0height);
  468. pxp_set_output_alpha(0xff);
  469. pxp_set_input_addr(s0buf, s0ubuf, s0vbuf);
  470. pxp_set_s0_input_size(0, 0, s0width, s0height);
  471. pxp_set_s0_background_color(0);
  472. pxp_set_color_space_conversion_coefficient(PXP_CSCCOEFF_YCBCR2RGB);
  473. if (outformat == PXP_OUT_FORMAT_ARGB888) {
  474. if(s0format == PXP_S0_FORMAT_ARGB888) {
  475. pxp_overlay_set_addr(PXP_OL0, s0buf);
  476. pxp_overlay_set_size(PXP_OL0, 0, 0, s0width, s0height);
  477. pxp_overlay_set_alpha_value(PXP_OL0, 0xff);
  478. pxp_overlay_set_format(PXP_OL0, PXP_OL_FORMAT_ARGB8888);
  479. pxp_overlay_set_alpha_cntl_type(PXP_OL0, PXP_OL_ALPHA_CNTL_TYPE_ROPS);
  480. pxp_overlay_set_rop(PXP_OL0, 3);
  481. pxp_overlay_enable(PXP_OL0, 1);
  482. pxp_set_s0_cropping_size(0, 0, 0, 0);
  483. crop_enable = 1;
  484. s0format = PXP_S0_FORMAT_RGB888;
  485. } else {
  486. alpha_out_enable = 1;
  487. }
  488. }
  489. pxp_param param;
  490. memset(&param, 0, sizeof(pxp_param));
  491. param.in_format = s0format;
  492. param.out_format = outformat;
  493. param.in_interlace_enable = 0;
  494. param.out_interlace_enable = 0;
  495. param.rotate = outangle;
  496. param.vflip_enable = 0;
  497. #ifdef PXP_OUTPUT_MIRROR
  498. param.hflip_enable = 1;
  499. #endif
  500. param.crop_enable = crop_enable;
  501. param.scale_enable = 0;
  502. param.alpha_out_enable = alpha_out_enable;
  503. pxp_set_control_param(&param);
  504. xQueueReset(pxp_done);
  505. pxp_start();
  506. if (xQueueReceive(pxp_done, NULL, pdMS_TO_TICKS(1000)) != pdTRUE) {
  507. printf("pxp timeout.\n");
  508. ret = -ETIMEDOUT;
  509. }
  510. xSemaphoreGive(pxp_mutex);
  511. return ret;
  512. }
  513. static void pxp_interupt_handler(void *param)
  514. {
  515. uint32_t status = PXP_READL(PXP_STAT);
  516. PXP_WRITEL(status, PXP_STAT_CLR);
  517. if (status & 1) {
  518. xQueueSendFromISR(pxp_done, NULL, 0);
  519. }
  520. }
  521. int pxp_init(void)
  522. {
  523. pxp_mutex = xSemaphoreCreateMutex();
  524. pxp_done = xQueueCreate(1, 0);
  525. g_pxp = (struct ark_pxp_data *)malloc(sizeof(struct ark_pxp_data));
  526. if(!g_pxp) {
  527. printf("ERR: rt_malloc failed\n");
  528. return -1;
  529. }
  530. memset(g_pxp, 0, sizeof(struct ark_pxp_data));
  531. g_pxp->block_size = PXP_BLOCK_SIZE_8X8;
  532. pxp_reset();
  533. pxp_set_color_space_conversion_coefficient(PXP_CSCCOEFF_YCBCR2RGB);
  534. request_irq(PXP_IRQn, 0, pxp_interupt_handler, NULL);
  535. return 0;
  536. }