1 /*
2 * Copyright (c) 2020 Hubert Miś
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/misc/ft8xx/ft8xx_copro.h>
8
9 #include <stdint.h>
10 #include <string.h>
11
12 #include <zephyr/drivers/misc/ft8xx/ft8xx_common.h>
13 #include <zephyr/drivers/misc/ft8xx/ft8xx_memory.h>
14 #include "ft8xx_drv.h"
15
16 #define FT800_RAM_CMD_SIZE 4096UL
17
18 enum {
19 CMD_DLSTART = 0xffffff00,
20 CMD_SWAP = 0xffffff01,
21 CMD_TEXT = 0xffffff0c,
22 CMD_NUMBER = 0xffffff2e,
23 CMD_CALIBRATE = 0xffffff15,
24 } ft8xx_cmd;
25
26 static uint16_t reg_cmd_read;
27 static uint16_t reg_cmd_write;
28
ram_cmd_fullness(void)29 static uint16_t ram_cmd_fullness(void)
30 {
31 return (reg_cmd_write - reg_cmd_read) % 4096UL;
32 }
33
ram_cmd_freespace(void)34 static uint16_t ram_cmd_freespace(void)
35 {
36 return (FT800_RAM_CMD_SIZE - 4UL) - ram_cmd_fullness();
37 }
38
refresh_reg_cmd_read(void)39 static void refresh_reg_cmd_read(void)
40 {
41 reg_cmd_read = ft8xx_rd32(FT800_REG_CMD_READ);
42 }
43
flush_reg_cmd_write(void)44 static void flush_reg_cmd_write(void)
45 {
46 ft8xx_wr32(FT800_REG_CMD_WRITE, reg_cmd_write);
47 }
48
increase_reg_cmd_write(uint16_t value)49 static void increase_reg_cmd_write(uint16_t value)
50 {
51 reg_cmd_write = (reg_cmd_write + value) % FT800_RAM_CMD_SIZE;
52 }
53
ft8xx_copro_cmd(uint32_t cmd)54 void ft8xx_copro_cmd(uint32_t cmd)
55 {
56 while (ram_cmd_freespace() < sizeof(cmd)) {
57 refresh_reg_cmd_read();
58 }
59
60 ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, cmd);
61 increase_reg_cmd_write(sizeof(cmd));
62
63 flush_reg_cmd_write();
64 }
65
ft8xx_copro_cmd_dlstart(void)66 void ft8xx_copro_cmd_dlstart(void)
67 {
68 ft8xx_copro_cmd(CMD_DLSTART);
69 }
70
ft8xx_copro_cmd_swap(void)71 void ft8xx_copro_cmd_swap(void)
72 {
73 ft8xx_copro_cmd(CMD_SWAP);
74 }
75
ft8xx_copro_cmd_text(int16_t x,int16_t y,int16_t font,uint16_t options,const char * s)76 void ft8xx_copro_cmd_text(int16_t x,
77 int16_t y,
78 int16_t font,
79 uint16_t options,
80 const char *s)
81 {
82 const uint16_t str_bytes = strlen(s) + 1;
83 const uint16_t padding_bytes = (4 - (str_bytes % 4)) % 4;
84 const uint16_t cmd_size = sizeof(CMD_TEXT) +
85 sizeof(x) +
86 sizeof(y) +
87 sizeof(font) +
88 sizeof(options) +
89 str_bytes +
90 padding_bytes;
91
92 while (ram_cmd_freespace() < cmd_size) {
93 refresh_reg_cmd_read();
94 }
95
96 ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_TEXT);
97 increase_reg_cmd_write(sizeof(CMD_TEXT));
98
99 ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, x);
100 increase_reg_cmd_write(sizeof(x));
101
102 ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, y);
103 increase_reg_cmd_write(sizeof(y));
104
105 ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, font);
106 increase_reg_cmd_write(sizeof(font));
107
108 ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, options);
109 increase_reg_cmd_write(sizeof(options));
110
111 (void)ft8xx_drv_write(FT800_RAM_CMD + reg_cmd_write, s, str_bytes);
112 increase_reg_cmd_write(str_bytes + padding_bytes);
113
114 flush_reg_cmd_write();
115 }
116
ft8xx_copro_cmd_number(int16_t x,int16_t y,int16_t font,uint16_t options,int32_t n)117 void ft8xx_copro_cmd_number(int16_t x,
118 int16_t y,
119 int16_t font,
120 uint16_t options,
121 int32_t n)
122 {
123 const uint16_t cmd_size = sizeof(CMD_NUMBER) +
124 sizeof(x) +
125 sizeof(y) +
126 sizeof(font) +
127 sizeof(options) +
128 sizeof(n);
129
130 while (ram_cmd_freespace() < cmd_size) {
131 refresh_reg_cmd_read();
132 }
133
134 ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_NUMBER);
135 increase_reg_cmd_write(sizeof(CMD_NUMBER));
136
137 ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, x);
138 increase_reg_cmd_write(sizeof(x));
139
140 ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, y);
141 increase_reg_cmd_write(sizeof(y));
142
143 ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, font);
144 increase_reg_cmd_write(sizeof(font));
145
146 ft8xx_wr16(FT800_RAM_CMD + reg_cmd_write, options);
147 increase_reg_cmd_write(sizeof(options));
148
149 ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, n);
150 increase_reg_cmd_write(sizeof(n));
151
152 flush_reg_cmd_write();
153 }
154
ft8xx_copro_cmd_calibrate(uint32_t * result)155 void ft8xx_copro_cmd_calibrate(uint32_t *result)
156 {
157 const uint16_t cmd_size = sizeof(CMD_CALIBRATE) + sizeof(uint32_t);
158 uint32_t result_address;
159
160 while (ram_cmd_freespace() < cmd_size) {
161 refresh_reg_cmd_read();
162 }
163
164 ft8xx_wr32(FT800_RAM_CMD + reg_cmd_write, CMD_CALIBRATE);
165 increase_reg_cmd_write(sizeof(CMD_CALIBRATE));
166
167 result_address = FT800_RAM_CMD + reg_cmd_write;
168 ft8xx_wr32(result_address, 1UL);
169 increase_reg_cmd_write(sizeof(uint32_t));
170
171 flush_reg_cmd_write();
172
173 /* Wait until calibration is finished. */
174 while (ram_cmd_fullness() > 0) {
175 refresh_reg_cmd_read();
176 }
177
178 *result = ft8xx_rd32(result_address);
179 }
180