nrf_gfx.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /**
  2. * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include "sdk_common.h"
  41. #if NRF_MODULE_ENABLED(NRF_GFX)
  42. #include "nrf_gfx.h"
  43. #include <stdlib.h>
  44. #include "app_util_platform.h"
  45. #include "nrf_assert.h"
  46. #define NRF_LOG_MODULE_NAME gfx
  47. #include "nrf_log.h"
  48. NRF_LOG_MODULE_REGISTER();
  49. static inline void pixel_draw(nrf_lcd_t const * p_instance,
  50. uint16_t x,
  51. uint16_t y,
  52. uint32_t color)
  53. {
  54. uint16_t lcd_width = nrf_gfx_width_get(p_instance);
  55. uint16_t lcd_height = nrf_gfx_height_get(p_instance);
  56. if ((x >= lcd_width) || (y >= lcd_height))
  57. {
  58. return;
  59. }
  60. p_instance->lcd_pixel_draw(x, y, color);
  61. }
  62. static void rect_draw(nrf_lcd_t const * p_instance,
  63. uint16_t x,
  64. uint16_t y,
  65. uint16_t width,
  66. uint16_t height,
  67. uint32_t color)
  68. {
  69. uint16_t lcd_width = nrf_gfx_width_get(p_instance);
  70. uint16_t lcd_height = nrf_gfx_height_get(p_instance);
  71. if ((x >= lcd_width) || (y >= lcd_height))
  72. {
  73. return;
  74. }
  75. if (width > (lcd_width - x))
  76. {
  77. width = lcd_width - x;
  78. }
  79. if (height > (lcd_height - y))
  80. {
  81. height = lcd_height - y;
  82. }
  83. p_instance->lcd_rect_draw(x, y, width, height, color);
  84. }
  85. static void line_draw(nrf_lcd_t const * p_instance,
  86. uint16_t x_0,
  87. uint16_t y_0,
  88. uint16_t x_1,
  89. int16_t y_1,
  90. uint32_t color)
  91. {
  92. uint16_t x = x_0;
  93. uint16_t y = y_0;
  94. int16_t d;
  95. int16_t d_1;
  96. int16_t d_2;
  97. int16_t ai;
  98. int16_t bi;
  99. int16_t xi = (x_0 < x_1) ? 1 : (-1);
  100. int16_t yi = (y_0 < y_1) ? 1 : (-1);
  101. bool swapped = false;
  102. d_1 = abs(x_1 - x_0);
  103. d_2 = abs(y_1 - y_0);
  104. pixel_draw(p_instance, x, y, color);
  105. if (d_1 < d_2)
  106. {
  107. d_1 = d_1 ^ d_2;
  108. d_2 = d_1 ^ d_2;
  109. d_1 = d_2 ^ d_1;
  110. swapped = true;
  111. }
  112. ai = (d_2 - d_1) * 2;
  113. bi = d_2 * 2;
  114. d = bi - d_1;
  115. while ((y != y_1) || (x != x_1))
  116. {
  117. if (d >= 0)
  118. {
  119. x += xi;
  120. y += yi;
  121. d += ai;
  122. }
  123. else
  124. {
  125. d += bi;
  126. if (swapped)
  127. {
  128. y += yi;
  129. }
  130. else
  131. {
  132. x += xi;
  133. }
  134. }
  135. pixel_draw(p_instance, x, y, color);
  136. }
  137. }
  138. static void write_character(nrf_lcd_t const * p_instance,
  139. nrf_gfx_font_desc_t const * p_font,
  140. uint8_t character,
  141. uint16_t * p_x,
  142. uint16_t y,
  143. uint16_t font_color)
  144. {
  145. uint8_t char_idx = character - p_font->startChar;
  146. uint16_t bytes_in_line = CEIL_DIV(p_font->charInfo[char_idx].widthBits, 8);
  147. if (character == ' ')
  148. {
  149. *p_x += p_font->height / 2;
  150. return;
  151. }
  152. for (uint16_t i = 0; i < p_font->height; i++)
  153. {
  154. for (uint16_t j = 0; j < bytes_in_line; j++)
  155. {
  156. for (uint8_t k = 0; k < 8; k++)
  157. {
  158. if ((1 << (7 - k)) &
  159. p_font->data[p_font->charInfo[char_idx].offset + i * bytes_in_line + j])
  160. {
  161. pixel_draw(p_instance, *p_x + j * 8 + k, y + i, font_color);
  162. }
  163. }
  164. }
  165. }
  166. *p_x += p_font->charInfo[char_idx].widthBits + p_font->spacePixels;
  167. }
  168. ret_code_t nrf_gfx_init(nrf_lcd_t const * p_instance)
  169. {
  170. ASSERT(p_instance != NULL);
  171. ASSERT(p_instance->p_lcd_cb->state == NRFX_DRV_STATE_UNINITIALIZED);
  172. ASSERT(p_instance->lcd_init != NULL);
  173. ASSERT(p_instance->lcd_uninit != NULL);
  174. ASSERT(p_instance->lcd_pixel_draw != NULL);
  175. ASSERT(p_instance->lcd_rect_draw != NULL);
  176. ASSERT(p_instance->lcd_display != NULL);
  177. ASSERT(p_instance->lcd_rotation_set != NULL);
  178. ASSERT(p_instance->lcd_display_invert != NULL);
  179. ASSERT(p_instance->p_lcd_cb != NULL);
  180. ret_code_t err_code;
  181. err_code = p_instance->lcd_init();
  182. if (err_code == NRF_SUCCESS)
  183. {
  184. p_instance->p_lcd_cb->state = NRFX_DRV_STATE_INITIALIZED;
  185. }
  186. return err_code;
  187. }
  188. void nrf_gfx_uninit(nrf_lcd_t const * p_instance)
  189. {
  190. ASSERT(p_instance != NULL);
  191. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  192. p_instance->p_lcd_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
  193. p_instance->lcd_uninit();
  194. }
  195. void nrf_gfx_point_draw(nrf_lcd_t const * p_instance,
  196. nrf_gfx_point_t const * p_point,
  197. uint32_t color)
  198. {
  199. ASSERT(p_instance != NULL);
  200. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  201. ASSERT(p_point != NULL);
  202. pixel_draw(p_instance, p_point->x, p_point->y, color);
  203. }
  204. ret_code_t nrf_gfx_line_draw(nrf_lcd_t const * p_instance,
  205. nrf_gfx_line_t const * p_line,
  206. uint32_t color)
  207. {
  208. ASSERT(p_instance != NULL);
  209. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  210. ASSERT(p_line != NULL);
  211. uint16_t x_thick = 0;
  212. uint16_t y_thick = 0;
  213. if (((p_line->x_start > nrf_gfx_width_get(p_instance)) &&
  214. (p_line->x_end > nrf_gfx_height_get(p_instance))) ||
  215. ((p_line->y_start > nrf_gfx_width_get(p_instance)) &&
  216. (p_line->y_end > nrf_gfx_height_get(p_instance))))
  217. {
  218. return NRF_ERROR_INVALID_PARAM;
  219. }
  220. if (abs(p_line->x_start - p_line->x_end) > abs(p_line->y_start - p_line->y_end))
  221. {
  222. y_thick = p_line->thickness;
  223. }
  224. else
  225. {
  226. x_thick = p_line->thickness;
  227. }
  228. if ((p_line->x_start == p_line->x_end) || (p_line->y_start == p_line->y_end))
  229. {
  230. rect_draw(p_instance,
  231. p_line->x_start,
  232. p_line->y_start,
  233. abs(p_line->x_end - p_line->x_start) + x_thick,
  234. abs(p_line->y_end - p_line->y_start) + y_thick,
  235. color);
  236. }
  237. else
  238. {
  239. if (x_thick > 0)
  240. {
  241. for (uint16_t i = 0; i < p_line->thickness; i++)
  242. {
  243. line_draw(p_instance,
  244. p_line->x_start + i,
  245. p_line->y_start,
  246. p_line->x_end + i,
  247. p_line->y_end,
  248. color);
  249. }
  250. }
  251. else if (y_thick > 0)
  252. {
  253. for (uint16_t i = 0; i < p_line->thickness; i++)
  254. {
  255. line_draw(p_instance,
  256. p_line->x_start,
  257. p_line->y_start + i,
  258. p_line->x_end,
  259. p_line->y_end + i,
  260. color);
  261. }
  262. }
  263. else
  264. {
  265. line_draw(p_instance,
  266. p_line->x_start + x_thick,
  267. p_line->y_start + y_thick,
  268. p_line->x_end + x_thick,
  269. p_line->y_end + y_thick,
  270. color);
  271. }
  272. }
  273. return NRF_SUCCESS;
  274. }
  275. ret_code_t nrf_gfx_circle_draw(nrf_lcd_t const * p_instance,
  276. nrf_gfx_circle_t const * p_circle,
  277. uint32_t color,
  278. bool fill)
  279. {
  280. ASSERT(p_instance != NULL);
  281. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  282. ASSERT(p_circle != NULL);
  283. int16_t y = 0;
  284. int16_t err = 0;
  285. int16_t x = p_circle->r;
  286. if ((p_circle->x - p_circle->r > nrf_gfx_width_get(p_instance)) ||
  287. (p_circle->y - p_circle->r > nrf_gfx_height_get(p_instance)))
  288. {
  289. return NRF_ERROR_INVALID_PARAM;
  290. }
  291. while (x >= y)
  292. {
  293. if (fill)
  294. {
  295. if ((-y + p_circle->x < 0) || (-x + p_circle->x < 0))
  296. {
  297. rect_draw(p_instance, 0, (-x + p_circle->y), (y + p_circle->x + 1), 1, color);
  298. rect_draw(p_instance, 0, (-y + p_circle->y), (x + p_circle->x + 1), 1, color);
  299. rect_draw(p_instance, 0, (y + p_circle->y), (x + p_circle->x + 1), 1, color);
  300. rect_draw(p_instance, 0, (x + p_circle->y), (y + p_circle->x + 1), 1, color);
  301. }
  302. else
  303. {
  304. rect_draw(p_instance, (-y + p_circle->x), (-x + p_circle->y), (2 * y + 1), 1, color);
  305. rect_draw(p_instance, (-x + p_circle->x), (-y + p_circle->y), (2 * x + 1), 1, color);
  306. rect_draw(p_instance, (-x + p_circle->x), (y + p_circle->y), (2 * x + 1), 1, color);
  307. rect_draw(p_instance, (-y + p_circle->x), (x + p_circle->y), (2 * y + 1), 1, color);
  308. }
  309. }
  310. else
  311. {
  312. pixel_draw(p_instance, (y + p_circle->x), (x + p_circle->y), color);
  313. pixel_draw(p_instance, (-y + p_circle->x), (x + p_circle->y), color);
  314. pixel_draw(p_instance, (x + p_circle->x), (y + p_circle->y), color);
  315. pixel_draw(p_instance, (-x + p_circle->x), (y + p_circle->y), color);
  316. pixel_draw(p_instance, (-y + p_circle->x), (-x + p_circle->y), color);
  317. pixel_draw(p_instance, (y + p_circle->x), (-x + p_circle->y), color);
  318. pixel_draw(p_instance, (-x + p_circle->x), (-y + p_circle->y), color);
  319. pixel_draw(p_instance, (x + p_circle->x), (-y + p_circle->y), color);
  320. }
  321. if (err <= 0)
  322. {
  323. y += 1;
  324. err += 2 * y + 1;
  325. }
  326. if (err > 0)
  327. {
  328. x -= 1;
  329. err -= 2 * x + 1;
  330. }
  331. }
  332. return NRF_SUCCESS;
  333. }
  334. ret_code_t nrf_gfx_rect_draw(nrf_lcd_t const * p_instance,
  335. nrf_gfx_rect_t const * p_rect,
  336. uint16_t thickness,
  337. uint32_t color,
  338. bool fill)
  339. {
  340. ASSERT(p_instance != NULL);
  341. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  342. ASSERT(p_rect != NULL);
  343. uint16_t rect_width = p_rect->width - thickness;
  344. uint16_t rect_height = p_rect->height - thickness;
  345. if ((p_rect->width == 1) ||
  346. (p_rect->height == 1) ||
  347. (thickness * 2 > p_rect->width) ||
  348. (thickness * 2 > p_rect->height) ||
  349. ((p_rect->x > nrf_gfx_width_get(p_instance)) &&
  350. (p_rect->y > nrf_gfx_height_get(p_instance))))
  351. {
  352. return NRF_ERROR_INVALID_PARAM;
  353. }
  354. if (fill)
  355. {
  356. rect_draw(p_instance,
  357. p_rect->x,
  358. p_rect->y,
  359. p_rect->width,
  360. p_rect->height,
  361. color);
  362. }
  363. else
  364. {
  365. nrf_gfx_line_t line;
  366. // Top horizontal line.
  367. line.x_start = p_rect->x;
  368. line.y_start = p_rect->y;
  369. line.x_end = p_rect->x + p_rect->width;
  370. line.y_end = p_rect->y;
  371. line.thickness = thickness;
  372. (void)nrf_gfx_line_draw(p_instance, &line, color);
  373. // Bottom horizontal line.
  374. line.x_start = p_rect->x;
  375. line.y_start = p_rect->y + rect_height;
  376. line.x_end = p_rect->x + p_rect->width;
  377. line.y_end = p_rect->y + rect_height;
  378. (void)nrf_gfx_line_draw(p_instance, &line, color);
  379. // Left vertical line.
  380. line.x_start = p_rect->x;
  381. line.y_start = p_rect->y + thickness;
  382. line.x_end = p_rect->x;
  383. line.y_end = p_rect->y + rect_height;
  384. (void)nrf_gfx_line_draw(p_instance, &line, color);
  385. // Right vertical line.
  386. line.x_start = p_rect->x + rect_width;
  387. line.y_start = p_rect->y + thickness;
  388. line.x_end = p_rect->x + rect_width;
  389. line.y_end = p_rect->y + rect_height;
  390. (void)nrf_gfx_line_draw(p_instance, &line, color);
  391. }
  392. return NRF_SUCCESS;
  393. }
  394. void nrf_gfx_screen_fill(nrf_lcd_t const * p_instance, uint32_t color)
  395. {
  396. rect_draw(p_instance, 0, 0, nrf_gfx_width_get(p_instance), nrf_gfx_height_get(p_instance), color);
  397. }
  398. ret_code_t nrf_gfx_bmp565_draw(nrf_lcd_t const * p_instance,
  399. nrf_gfx_rect_t const * p_rect,
  400. uint16_t const * img_buf)
  401. {
  402. ASSERT(p_instance != NULL);
  403. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  404. ASSERT(p_rect != NULL);
  405. ASSERT(img_buf != NULL);
  406. if ((p_rect->x > nrf_gfx_width_get(p_instance)) || (p_rect->y > nrf_gfx_height_get(p_instance)))
  407. {
  408. return NRF_ERROR_INVALID_PARAM;
  409. }
  410. size_t idx;
  411. uint16_t pixel;
  412. uint8_t padding = p_rect->width % 2;
  413. for (int32_t i = 0; i < p_rect->height; i++)
  414. {
  415. for (uint32_t j = 0; j < p_rect->width; j++)
  416. {
  417. idx = (uint32_t)((p_rect->height - i - 1) * (p_rect->width + padding) + j);
  418. pixel = (img_buf[idx] >> 8) | (img_buf[idx] << 8);
  419. pixel_draw(p_instance, p_rect->x + j, p_rect->y + i, pixel);
  420. }
  421. }
  422. return NRF_SUCCESS;
  423. }
  424. void nrf_gfx_background_set(nrf_lcd_t const * p_instance, uint16_t const * img_buf)
  425. {
  426. ASSERT(p_instance != NULL);
  427. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  428. ASSERT(img_buf != NULL);
  429. const nrf_gfx_rect_t rectangle =
  430. {
  431. .x = 0,
  432. .y = 0,
  433. .width = nrf_gfx_width_get(p_instance),
  434. .height = nrf_gfx_height_get(p_instance)
  435. };
  436. (void)nrf_gfx_bmp565_draw(p_instance, &rectangle, img_buf);
  437. }
  438. void nrf_gfx_display(nrf_lcd_t const * p_instance)
  439. {
  440. ASSERT(p_instance != NULL);
  441. p_instance->lcd_display();
  442. }
  443. void nrf_gfx_rotation_set(nrf_lcd_t const * p_instance, nrf_lcd_rotation_t rotation)
  444. {
  445. ASSERT(p_instance != NULL);
  446. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  447. bool rotated = (bool)(p_instance->p_lcd_cb->rotation % 2);
  448. uint16_t height = !rotated ? nrf_gfx_height_get(p_instance) :
  449. nrf_gfx_width_get(p_instance);
  450. uint16_t width = !rotated ? nrf_gfx_width_get(p_instance) :
  451. nrf_gfx_height_get(p_instance);
  452. p_instance->p_lcd_cb->rotation = rotation;
  453. switch (rotation) {
  454. case NRF_LCD_ROTATE_0:
  455. p_instance->p_lcd_cb->height = height;
  456. p_instance->p_lcd_cb->width = width;
  457. break;
  458. case NRF_LCD_ROTATE_90:
  459. p_instance->p_lcd_cb->height = width;
  460. p_instance->p_lcd_cb->width = height;
  461. break;
  462. case NRF_LCD_ROTATE_180:
  463. p_instance->p_lcd_cb->height = height;
  464. p_instance->p_lcd_cb->width = width;
  465. break;
  466. case NRF_LCD_ROTATE_270:
  467. p_instance->p_lcd_cb->height = width;
  468. p_instance->p_lcd_cb->width = height;
  469. break;
  470. default:
  471. break;
  472. }
  473. p_instance->lcd_rotation_set(rotation);
  474. }
  475. void nrf_gfx_invert(nrf_lcd_t const * p_instance, bool invert)
  476. {
  477. ASSERT(p_instance != NULL);
  478. p_instance->lcd_display_invert(invert);
  479. }
  480. ret_code_t nrf_gfx_print(nrf_lcd_t const * p_instance,
  481. nrf_gfx_point_t const * p_point,
  482. uint16_t font_color,
  483. const char * string,
  484. const nrf_gfx_font_desc_t * p_font,
  485. bool wrap)
  486. {
  487. ASSERT(p_instance != NULL);
  488. ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
  489. ASSERT(p_point != NULL);
  490. ASSERT(string != NULL);
  491. ASSERT(p_font != NULL);
  492. uint16_t x = p_point->x;
  493. uint16_t y = p_point->y;
  494. if (y > (nrf_gfx_height_get(p_instance) - p_font->height))
  495. {
  496. // Not enough space to write even single char.
  497. return NRF_ERROR_INVALID_PARAM;
  498. }
  499. for (size_t i = 0; string[i] != '\0' ; i++)
  500. {
  501. if (string[i] == '\n')
  502. {
  503. x = p_point->x;
  504. y += p_font->height + p_font->height / 10;
  505. }
  506. else
  507. {
  508. write_character(p_instance, p_font, (uint8_t)string[i], &x, y, font_color);
  509. }
  510. uint8_t char_idx = string[i] - p_font->startChar;
  511. uint16_t char_width = string[i] == ' ' ? (p_font->height / 2) :
  512. p_font->charInfo[char_idx].widthBits;
  513. if (x > (nrf_gfx_width_get(p_instance) - char_width))
  514. {
  515. if (wrap)
  516. {
  517. x = p_point->x;
  518. y += p_font->height + p_font->height / 10;
  519. }
  520. else
  521. {
  522. break;
  523. }
  524. if (y > (nrf_gfx_height_get(p_instance) - p_font->height))
  525. {
  526. break;
  527. }
  528. }
  529. }
  530. return NRF_SUCCESS;
  531. }
  532. uint16_t nrf_gfx_height_get(nrf_lcd_t const * p_instance)
  533. {
  534. ASSERT(p_instance != NULL);
  535. return p_instance->p_lcd_cb->height;
  536. }
  537. uint16_t nrf_gfx_width_get(nrf_lcd_t const * p_instance)
  538. {
  539. ASSERT(p_instance != NULL);
  540. return p_instance->p_lcd_cb->width;
  541. }
  542. #endif //NRF_MODULE_ENABLED(NRF_GFX)