diff options
| author | Your Name <you@example.com> | 2026-05-20 02:14:45 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-20 02:14:45 +0530 |
| commit | 899016795c389151e6b486ec470653f5688e5c5f (patch) | |
| tree | 64b4c732d6f585552fd14df5f47890764c66ac1a /components/axs15231b | |
| parent | 4f713120dbedd37a3512c2ec1af0766025a59d57 (diff) | |
feat: merge display-fix — touch driver, keyboard, WiFi setup UI
Squash-merge of feature/display-fix (27 commits):
- AXS15231B touch driver with coordinate parsing (touch.c/h)
- On-screen keyboard with layout/hit detection (keyboard.c/h)
- WiFi setup state machine + config_add_wifi (wifi_setup.c/h)
- Web-based WiFi setup via captive portal
- Display rotation fix (stride=480), color fixes, DMA byte-swap
- WiFi QR code on BOOT and ERROR screens
- ERROR state transition after WiFi retries exhausted
- Unit tests: test_touch, test_keyboard, test_wifi_setup
- Integration test: wifi_setup.mjs
- E2E test: wifi-setup.spec.mjs
- Per-board hardware locks for flash targets
Conflicts resolved: took master for config/cvm/api/main (more current),
took display-fix for display/axs15231b (newer fixes).
Diffstat (limited to 'components/axs15231b')
| -rw-r--r-- | components/axs15231b/axs15231b.c | 237 | ||||
| -rw-r--r-- | components/axs15231b/include/axs15231b.h | 5 |
2 files changed, 159 insertions, 83 deletions
diff --git a/components/axs15231b/axs15231b.c b/components/axs15231b/axs15231b.c index dd7145a..00e8467 100644 --- a/components/axs15231b/axs15231b.c +++ b/components/axs15231b/axs15231b.c | |||
| @@ -29,10 +29,17 @@ static const char *TAG = "axs15231b"; | |||
| 29 | #define MADCTL_MV 0x20 | 29 | #define MADCTL_MV 0x20 |
| 30 | #define MADCTL_RGB 0x00 | 30 | #define MADCTL_RGB 0x00 |
| 31 | 31 | ||
| 32 | #define QSPI_CMD_REG_WRITE 0x02 | ||
| 33 | #define QSPI_CMD_DATA_WRITE 0x32 | ||
| 34 | #define QSPI_DATA_ADDR 0x003C00 | ||
| 35 | |||
| 32 | static spi_device_handle_t s_spi = NULL; | 36 | static spi_device_handle_t s_spi = NULL; |
| 33 | static uint16_t *s_fb = NULL; | 37 | static uint16_t *s_fb = NULL; |
| 34 | static int s_width = AXS15231B_WIDTH; | 38 | static int s_width = AXS15231B_WIDTH; |
| 35 | static int s_height = AXS15231B_HEIGHT; | 39 | static int s_height = AXS15231B_HEIGHT; |
| 40 | static int s_stride = AXS15231B_WIDTH; | ||
| 41 | static uint8_t *s_swap_buf = NULL; | ||
| 42 | #define SWAP_BUF_PIXELS 2048 | ||
| 36 | 43 | ||
| 37 | typedef struct { | 44 | typedef struct { |
| 38 | uint8_t cmd; | 45 | uint8_t cmd; |
| @@ -41,28 +48,92 @@ typedef struct { | |||
| 41 | uint16_t delay_ms; | 48 | uint16_t delay_ms; |
| 42 | } init_cmd_t; | 49 | } init_cmd_t; |
| 43 | 50 | ||
| 44 | static esp_err_t send_cmd(uint8_t cmd) { | 51 | static inline void cs_low(void) { |
| 45 | spi_transaction_t t = {0}; | 52 | gpio_set_level(AXS15231B_PIN_CS, 0); |
| 46 | t.length = 8; | 53 | } |
| 47 | t.tx_data[0] = cmd; | 54 | |
| 48 | t.flags = SPI_TRANS_USE_TXDATA; | 55 | static inline void cs_high(void) { |
| 49 | return spi_device_polling_transmit(s_spi, &t); | 56 | gpio_set_level(AXS15231B_PIN_CS, 1); |
| 57 | } | ||
| 58 | |||
| 59 | static void cs_init(void) { | ||
| 60 | gpio_config_t cfg = { | ||
| 61 | .pin_bit_mask = (1ULL << AXS15231B_PIN_CS), | ||
| 62 | .mode = GPIO_MODE_OUTPUT, | ||
| 63 | .pull_up_en = GPIO_PULLUP_DISABLE, | ||
| 64 | .pull_down_en = GPIO_PULLDOWN_DISABLE, | ||
| 65 | .intr_type = GPIO_INTR_DISABLE, | ||
| 66 | }; | ||
| 67 | gpio_config(&cfg); | ||
| 68 | gpio_set_level(AXS15231B_PIN_CS, 1); | ||
| 69 | } | ||
| 70 | |||
| 71 | static void qspi_write_command(uint8_t lcd_cmd) { | ||
| 72 | spi_transaction_ext_t t = {0}; | ||
| 73 | t.base.flags = SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR; | ||
| 74 | t.base.cmd = QSPI_CMD_REG_WRITE; | ||
| 75 | t.base.addr = ((uint32_t)lcd_cmd) << 8; | ||
| 76 | t.base.tx_buffer = NULL; | ||
| 77 | t.base.length = 0; | ||
| 78 | cs_low(); | ||
| 79 | spi_device_polling_transmit(s_spi, (spi_transaction_t *)&t); | ||
| 80 | cs_high(); | ||
| 81 | } | ||
| 82 | |||
| 83 | static void qspi_write_cmd_data8(uint8_t lcd_cmd, uint8_t d) { | ||
| 84 | spi_transaction_ext_t t = {0}; | ||
| 85 | t.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR; | ||
| 86 | t.base.cmd = QSPI_CMD_REG_WRITE; | ||
| 87 | t.base.addr = ((uint32_t)lcd_cmd) << 8; | ||
| 88 | t.base.tx_data[0] = d; | ||
| 89 | t.base.length = 8; | ||
| 90 | cs_low(); | ||
| 91 | spi_device_polling_transmit(s_spi, (spi_transaction_t *)&t); | ||
| 92 | cs_high(); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void qspi_write_cmd_data16(uint8_t lcd_cmd, uint16_t d) { | ||
| 96 | spi_transaction_ext_t t = {0}; | ||
| 97 | t.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR; | ||
| 98 | t.base.cmd = QSPI_CMD_REG_WRITE; | ||
| 99 | t.base.addr = ((uint32_t)lcd_cmd) << 8; | ||
| 100 | t.base.tx_data[0] = d >> 8; | ||
| 101 | t.base.tx_data[1] = d & 0xFF; | ||
| 102 | t.base.length = 16; | ||
| 103 | cs_low(); | ||
| 104 | spi_device_polling_transmit(s_spi, (spi_transaction_t *)&t); | ||
| 105 | cs_high(); | ||
| 50 | } | 106 | } |
| 51 | 107 | ||
| 52 | static esp_err_t send_data(const uint8_t *data, int len) { | 108 | static void qspi_write_cmd_bytes(uint8_t lcd_cmd, const uint8_t *data, int len) { |
| 53 | if (len == 0) return ESP_OK; | 109 | if (len == 0) { |
| 54 | spi_transaction_t t = {0}; | 110 | qspi_write_command(lcd_cmd); |
| 55 | t.length = len * 8; | 111 | return; |
| 56 | t.tx_buffer = data; | 112 | } |
| 57 | t.flags = 0; | 113 | spi_transaction_ext_t t = {0}; |
| 58 | return spi_device_polling_transmit(s_spi, &t); | 114 | t.base.flags = SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR; |
| 115 | t.base.cmd = QSPI_CMD_REG_WRITE; | ||
| 116 | t.base.addr = ((uint32_t)lcd_cmd) << 8; | ||
| 117 | t.base.tx_buffer = data; | ||
| 118 | t.base.length = len * 8; | ||
| 119 | cs_low(); | ||
| 120 | spi_device_polling_transmit(s_spi, (spi_transaction_t *)&t); | ||
| 121 | cs_high(); | ||
| 59 | } | 122 | } |
| 60 | 123 | ||
| 61 | static esp_err_t send_cmd_data(uint8_t cmd, const uint8_t *data, int len) { | 124 | static void qspi_write_cmd_d16d16(uint8_t lcd_cmd, uint16_t d1, uint16_t d2) { |
| 62 | esp_err_t ret = send_cmd(cmd); | 125 | spi_transaction_ext_t t = {0}; |
| 63 | if (ret != ESP_OK) return ret; | 126 | t.base.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR; |
| 64 | if (len > 0) ret = send_data(data, len); | 127 | t.base.cmd = QSPI_CMD_REG_WRITE; |
| 65 | return ret; | 128 | t.base.addr = ((uint32_t)lcd_cmd) << 8; |
| 129 | t.base.tx_data[0] = d1 >> 8; | ||
| 130 | t.base.tx_data[1] = d1 & 0xFF; | ||
| 131 | t.base.tx_data[2] = d2 >> 8; | ||
| 132 | t.base.tx_data[3] = d2 & 0xFF; | ||
| 133 | t.base.length = 32; | ||
| 134 | cs_low(); | ||
| 135 | spi_device_polling_transmit(s_spi, (spi_transaction_t *)&t); | ||
| 136 | cs_high(); | ||
| 66 | } | 137 | } |
| 67 | 138 | ||
| 68 | static const uint8_t init_bb[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x5A,0xA5}; | 139 | static const uint8_t init_bb[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x5A,0xA5}; |
| @@ -136,20 +207,23 @@ esp_err_t axs15231b_init(void) { | |||
| 136 | esp_err_t ret; | 207 | esp_err_t ret; |
| 137 | 208 | ||
| 138 | spi_bus_config_t buscfg = { | 209 | spi_bus_config_t buscfg = { |
| 139 | .mosi_io_num = AXS15231B_PIN_D0, | 210 | .data0_io_num = AXS15231B_PIN_D0, |
| 211 | .data1_io_num = AXS15231B_PIN_D1, | ||
| 140 | .sclk_io_num = AXS15231B_PIN_CLK, | 212 | .sclk_io_num = AXS15231B_PIN_CLK, |
| 141 | .miso_io_num = -1, | 213 | .data2_io_num = AXS15231B_PIN_D2, |
| 142 | .quadwp_io_num = -1, | 214 | .data3_io_num = AXS15231B_PIN_D3, |
| 143 | .quadhd_io_num = -1, | ||
| 144 | .max_transfer_sz = 32768, | 215 | .max_transfer_sz = 32768, |
| 145 | }; | 216 | }; |
| 146 | 217 | ||
| 147 | spi_device_interface_config_t devcfg = { | 218 | spi_device_interface_config_t devcfg = { |
| 219 | .command_bits = 8, | ||
| 220 | .address_bits = 24, | ||
| 221 | .dummy_bits = 0, | ||
| 148 | .clock_speed_hz = 40 * 1000 * 1000, | 222 | .clock_speed_hz = 40 * 1000 * 1000, |
| 149 | .mode = 0, | 223 | .mode = 0, |
| 150 | .spics_io_num = AXS15231B_PIN_CS, | 224 | .spics_io_num = -1, |
| 151 | .queue_size = 7, | 225 | .queue_size = 7, |
| 152 | .flags = 0, | 226 | .flags = SPI_DEVICE_HALFDUPLEX, |
| 153 | }; | 227 | }; |
| 154 | 228 | ||
| 155 | ret = spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO); | 229 | ret = spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO); |
| @@ -164,6 +238,10 @@ esp_err_t axs15231b_init(void) { | |||
| 164 | return ret; | 238 | return ret; |
| 165 | } | 239 | } |
| 166 | 240 | ||
| 241 | spi_device_acquire_bus(s_spi, portMAX_DELAY); | ||
| 242 | |||
| 243 | cs_init(); | ||
| 244 | |||
| 167 | size_t fb_size = (size_t)s_width * s_height * 2; | 245 | size_t fb_size = (size_t)s_width * s_height * 2; |
| 168 | s_fb = heap_caps_malloc(fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); | 246 | s_fb = heap_caps_malloc(fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); |
| 169 | if (!s_fb) { | 247 | if (!s_fb) { |
| @@ -173,6 +251,13 @@ esp_err_t axs15231b_init(void) { | |||
| 173 | memset(s_fb, 0, fb_size); | 251 | memset(s_fb, 0, fb_size); |
| 174 | ESP_LOGI(TAG, "Framebuffer allocated: %zu bytes in PSRAM", fb_size); | 252 | ESP_LOGI(TAG, "Framebuffer allocated: %zu bytes in PSRAM", fb_size); |
| 175 | 253 | ||
| 254 | s_swap_buf = heap_caps_aligned_alloc(16, SWAP_BUF_PIXELS * 2, MALLOC_CAP_DMA); | ||
| 255 | if (!s_swap_buf) { | ||
| 256 | ESP_LOGE(TAG, "Failed to allocate DMA swap buffer (%d bytes)", SWAP_BUF_PIXELS * 2); | ||
| 257 | return ESP_ERR_NO_MEM; | ||
| 258 | } | ||
| 259 | ESP_LOGI(TAG, "DMA swap buffer: %d bytes in internal RAM", SWAP_BUF_PIXELS * 2); | ||
| 260 | |||
| 176 | gpio_config_t bl_cfg = { | 261 | gpio_config_t bl_cfg = { |
| 177 | .pin_bit_mask = (1ULL << AXS15231B_PIN_BL), | 262 | .pin_bit_mask = (1ULL << AXS15231B_PIN_BL), |
| 178 | .mode = GPIO_MODE_OUTPUT, | 263 | .mode = GPIO_MODE_OUTPUT, |
| @@ -182,40 +267,28 @@ esp_err_t axs15231b_init(void) { | |||
| 182 | }; | 267 | }; |
| 183 | gpio_config(&bl_cfg); | 268 | gpio_config(&bl_cfg); |
| 184 | 269 | ||
| 185 | send_cmd(SWRESET); | 270 | qspi_write_command(SWRESET); |
| 186 | vTaskDelay(pdMS_TO_TICKS(200)); | 271 | vTaskDelay(pdMS_TO_TICKS(200)); |
| 187 | 272 | ||
| 188 | for (int i = 0; i < INIT_CMD_COUNT; i++) { | 273 | for (int i = 0; i < INIT_CMD_COUNT; i++) { |
| 189 | ret = send_cmd_data(s_init_cmds[i].cmd, s_init_cmds[i].data, s_init_cmds[i].data_len); | 274 | qspi_write_cmd_bytes(s_init_cmds[i].cmd, s_init_cmds[i].data, s_init_cmds[i].data_len); |
| 190 | if (ret != ESP_OK) { | ||
| 191 | ESP_LOGE(TAG, "Init cmd 0x%02X failed: %s", s_init_cmds[i].cmd, esp_err_to_name(ret)); | ||
| 192 | return ret; | ||
| 193 | } | ||
| 194 | if (s_init_cmds[i].delay_ms > 0) { | 275 | if (s_init_cmds[i].delay_ms > 0) { |
| 195 | vTaskDelay(pdMS_TO_TICKS(s_init_cmds[i].delay_ms)); | 276 | vTaskDelay(pdMS_TO_TICKS(s_init_cmds[i].delay_ms)); |
| 196 | } | 277 | } |
| 197 | } | 278 | } |
| 198 | 279 | ||
| 199 | uint8_t madctl_val = MADCTL_MX | MADCTL_MV | MADCTL_RGB; | 280 | uint8_t madctl_val = MADCTL_RGB; |
| 200 | ret = send_cmd_data(MADCTL, &madctl_val, 1); | 281 | qspi_write_cmd_data8(MADCTL, madctl_val); |
| 201 | if (ret != ESP_OK) { | ||
| 202 | ESP_LOGE(TAG, "Failed to set rotation: %s", esp_err_to_name(ret)); | ||
| 203 | return ret; | ||
| 204 | } | ||
| 205 | 282 | ||
| 206 | uint8_t colmod_val = 0x55; | 283 | uint8_t colmod_val = 0x55; |
| 207 | ret = send_cmd_data(COLMOD, &colmod_val, 1); | 284 | qspi_write_cmd_data8(COLMOD, colmod_val); |
| 208 | if (ret != ESP_OK) { | ||
| 209 | ESP_LOGE(TAG, "Failed to set pixel format: %s", esp_err_to_name(ret)); | ||
| 210 | return ret; | ||
| 211 | } | ||
| 212 | 285 | ||
| 213 | axs15231b_fill_screen(0x0000); | 286 | axs15231b_fill_screen(0x0000); |
| 214 | axs15231b_flush(); | 287 | axs15231b_flush(); |
| 215 | 288 | ||
| 216 | axs15231b_set_backlight(true); | 289 | axs15231b_set_backlight(true); |
| 217 | 290 | ||
| 218 | ESP_LOGI(TAG, "AXS15231B initialized: %dx%d landscape", s_width, s_height); | 291 | ESP_LOGI(TAG, "AXS15231B initialized: %dx%d portrait", s_width, s_height); |
| 219 | return ESP_OK; | 292 | return ESP_OK; |
| 220 | } | 293 | } |
| 221 | 294 | ||
| @@ -224,9 +297,10 @@ void axs15231b_set_backlight(bool on) { | |||
| 224 | } | 297 | } |
| 225 | 298 | ||
| 226 | void axs15231b_fill_screen(uint16_t color) { | 299 | void axs15231b_fill_screen(uint16_t color) { |
| 227 | uint32_t pixels = (uint32_t)s_width * s_height; | 300 | for (int row = 0; row < s_height; row++) { |
| 228 | for (uint32_t i = 0; i < pixels; i++) { | 301 | for (int col = 0; col < s_width; col++) { |
| 229 | s_fb[i] = color; | 302 | s_fb[row * s_stride + col] = color; |
| 303 | } | ||
| 230 | } | 304 | } |
| 231 | } | 305 | } |
| 232 | 306 | ||
| @@ -234,48 +308,51 @@ void axs15231b_fill_rect(int x, int y, int w, int h, uint16_t color) { | |||
| 234 | if (x < 0 || y < 0 || x + w > s_width || y + h > s_height) return; | 308 | if (x < 0 || y < 0 || x + w > s_width || y + h > s_height) return; |
| 235 | for (int row = y; row < y + h; row++) { | 309 | for (int row = y; row < y + h; row++) { |
| 236 | for (int col = x; col < x + w; col++) { | 310 | for (int col = x; col < x + w; col++) { |
| 237 | s_fb[row * s_width + col] = color; | 311 | s_fb[row * s_stride + col] = color; |
| 238 | } | 312 | } |
| 239 | } | 313 | } |
| 240 | } | 314 | } |
| 241 | 315 | ||
| 242 | void axs15231b_flush(void) { | 316 | void axs15231b_flush(void) { |
| 243 | if (!s_spi || !s_fb) return; | 317 | if (!s_spi || !s_fb || !s_swap_buf) return; |
| 244 | 318 | ||
| 245 | uint8_t buf[4]; | 319 | qspi_write_cmd_d16d16(CASET, 0, s_width - 1); |
| 246 | buf[0] = 0; | 320 | qspi_write_cmd_d16d16(RASET, 0, s_height - 1); |
| 247 | buf[1] = 0; | 321 | qspi_write_command(RAMWR); |
| 248 | buf[2] = (s_width - 1) >> 8; | 322 | |
| 249 | buf[3] = (s_width - 1) & 0xFF; | 323 | bool first = true; |
| 250 | send_cmd_data(CASET, buf, 4); | 324 | cs_low(); |
| 251 | 325 | for (int row = 0; row < s_height; row++) { | |
| 252 | buf[0] = 0; | 326 | int chunk_remaining = s_width; |
| 253 | buf[1] = 0; | 327 | int col_offset = 0; |
| 254 | buf[2] = (s_height - 1) >> 8; | 328 | while (chunk_remaining > 0) { |
| 255 | buf[3] = (s_height - 1) & 0xFF; | 329 | int chunk_pixels = chunk_remaining < SWAP_BUF_PIXELS ? chunk_remaining : SWAP_BUF_PIXELS; |
| 256 | send_cmd_data(RASET, buf, 4); | 330 | int chunk_bytes = chunk_pixels * 2; |
| 257 | 331 | ||
| 258 | send_cmd(RAMWR); | 332 | uint8_t *src = (uint8_t *)(s_fb + row * s_stride + col_offset); |
| 259 | 333 | for (int i = 0; i < chunk_bytes; i += 2) { | |
| 260 | int total_bytes = s_width * s_height * 2; | 334 | s_swap_buf[i] = src[i + 1]; |
| 261 | int chunk_size = 32768; | 335 | s_swap_buf[i + 1] = src[i]; |
| 262 | int offset = 0; | 336 | } |
| 263 | uint8_t *fb_bytes = (uint8_t *)s_fb; | 337 | |
| 264 | 338 | spi_transaction_ext_t t = {0}; | |
| 265 | while (offset < total_bytes) { | 339 | if (first) { |
| 266 | int remaining = total_bytes - offset; | 340 | t.base.flags = SPI_TRANS_MODE_QIO; |
| 267 | int this_chunk = remaining < chunk_size ? remaining : chunk_size; | 341 | t.base.cmd = QSPI_CMD_DATA_WRITE; |
| 268 | 342 | t.base.addr = QSPI_DATA_ADDR; | |
| 269 | spi_transaction_t t = {0}; | 343 | first = false; |
| 270 | t.length = this_chunk * 8; | 344 | } else { |
| 271 | t.tx_buffer = fb_bytes + offset; | 345 | t.base.flags = SPI_TRANS_MODE_QIO | SPI_TRANS_VARIABLE_CMD | |
| 272 | esp_err_t ret = spi_device_polling_transmit(s_spi, &t); | 346 | SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_DUMMY; |
| 273 | if (ret != ESP_OK) { | 347 | } |
| 274 | ESP_LOGE(TAG, "Flush transfer failed at offset %d: %s", offset, esp_err_to_name(ret)); | 348 | t.base.tx_buffer = s_swap_buf; |
| 275 | return; | 349 | t.base.length = chunk_pixels * 16; |
| 350 | spi_device_polling_transmit(s_spi, (spi_transaction_t *)&t); | ||
| 351 | col_offset += chunk_pixels; | ||
| 352 | chunk_remaining -= chunk_pixels; | ||
| 276 | } | 353 | } |
| 277 | offset += this_chunk; | ||
| 278 | } | 354 | } |
| 355 | cs_high(); | ||
| 279 | } | 356 | } |
| 280 | 357 | ||
| 281 | int axs15231b_get_width(void) { return s_width; } | 358 | int axs15231b_get_width(void) { return s_width; } |
diff --git a/components/axs15231b/include/axs15231b.h b/components/axs15231b/include/axs15231b.h index 5ec017c..32c489f 100644 --- a/components/axs15231b/include/axs15231b.h +++ b/components/axs15231b/include/axs15231b.h | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | #include <stdint.h> | 5 | #include <stdint.h> |
| 6 | #include <stdbool.h> | 6 | #include <stdbool.h> |
| 7 | 7 | ||
| 8 | #define AXS15231B_WIDTH 480 | 8 | #define AXS15231B_WIDTH 320 |
| 9 | #define AXS15231B_HEIGHT 320 | 9 | #define AXS15231B_HEIGHT 480 |
| 10 | 10 | ||
| 11 | #define AXS15231B_PIN_CS 45 | 11 | #define AXS15231B_PIN_CS 45 |
| 12 | #define AXS15231B_PIN_CLK 47 | 12 | #define AXS15231B_PIN_CLK 47 |
| @@ -23,5 +23,4 @@ void axs15231b_fill_rect(int x, int y, int w, int h, uint16_t color); | |||
| 23 | void axs15231b_flush(void); | 23 | void axs15231b_flush(void); |
| 24 | int axs15231b_get_width(void); | 24 | int axs15231b_get_width(void); |
| 25 | int axs15231b_get_height(void); | 25 | int axs15231b_get_height(void); |
| 26 | |||
| 27 | #endif | 26 | #endif |