Removed excess trailing spaces before new lines on licenses.
[betaflight.git] / src / main / io / rcdevice_osd.c
blob252b551ef25501d5569c6a3ec1746caab7e6c8fa
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
24 #include "platform.h"
26 #ifdef USE_RCDEVICE
28 #include "io/rcdevice.h"
30 #include "pg/vcd.h"
32 #include "rcdevice_osd.h"
34 #define VIDEO_BUFFER_CHARS_PAL 480
36 static uint8_t columnCount = 30;
38 static runcamDevice_t runcamOSDDevice;
39 runcamDevice_t *osdDevice = &runcamOSDDevice;
41 static uint8_t video_system;
42 static uint16_t maxScreenSize = VIDEO_BUFFER_CHARS_PAL;
44 #ifdef USE_PARTICLE_DRAW
45 #define MAX_CHARS2UPDATE 20
46 static uint8_t screenBuffer[VIDEO_BUFFER_CHARS_PAL + 40]; // For faster writes
47 // we use memcpy so we
48 // need some space to
49 // don't overwrite
50 // buffer
51 static uint8_t shadowBuffer[VIDEO_BUFFER_CHARS_PAL];
52 static bool rcdeviceOSDLock = false;
53 #endif
55 bool rcdeviceOSDInit(const vcdProfile_t *vcdProfile)
57 if (!runcamDeviceInit(osdDevice)) {
58 return false;
61 if ((osdDevice->info.features & RCDEVICE_PROTOCOL_FEATURE_DISPLAYP_PORT) == 0) {
62 return false;
65 // get screen column count
66 runcamDeviceSettingDetail_t settingDetail;
67 if (!runcamDeviceGetSettingDetail(osdDevice, RCDEVICE_PROTOCOL_SETTINGID_DISP_COLUMNS, &settingDetail)) {
68 return false;
71 columnCount = settingDetail.value;
73 video_system = vcdProfile->video_system;
74 if (video_system == VIDEO_SYSTEM_AUTO) {
75 // fetch current video mode from device
76 runcamDeviceSettingDetail_t settingDetail;
77 if (!runcamDeviceGetSettingDetail(osdDevice, RCDEVICE_PROTOCOL_SETTINGID_DISP_TV_MODE, &settingDetail)) {
78 return false;
80 video_system = settingDetail.value;
81 } else {
82 // set video system
83 runcamDeviceWriteSettingResponse_t response;
84 uint8_t tvMode = 0;
85 if (video_system == VIDEO_SYSTEM_NTSC) {
86 tvMode = 0;
87 } else if (video_system == VIDEO_SYSTEM_PAL) {
88 tvMode = 1;
91 if (!runcamDeviceWriteSetting(osdDevice, RCDEVICE_PROTOCOL_SETTINGID_DISP_TV_MODE, &tvMode, sizeof(uint8_t), &response)) {
92 return false;
95 if (response.resultCode) {
96 return false;
100 // user bf charset
101 uint8_t charsetID = 0;
102 runcamDeviceWriteSettingResponse_t updateCharsetResp;
103 if (!runcamDeviceWriteSetting(osdDevice, RCDEVICE_PROTOCOL_SETTINGID_DISP_CHARSET, &charsetID, sizeof(uint8_t), &updateCharsetResp) || updateCharsetResp.resultCode != 0) {
104 return false;
107 #ifdef USE_PARTICLE_DRAW
108 memset(shadowBuffer, 2, VIDEO_BUFFER_CHARS_PAL);
109 #endif
111 // fill screen with ' '
112 rcdeviceOSDClearScreen(NULL);
113 return true;
116 int rcdeviceOSDGrab(displayPort_t *displayPort)
118 UNUSED(displayPort);
119 // osdResetAlarms();
120 // resumeRefreshAt = 0;
121 return 0;
124 int rcdeviceOSDRelease(displayPort_t *displayPort)
126 UNUSED(displayPort);
127 return 0;
130 int rcdeviceOSDDrawScreen(displayPort_t *displayPort)
132 UNUSED(displayPort);
134 #ifdef USE_PARTICLE_DRAW
135 static uint16_t pos = 0;
136 int k = 0;
138 if (!rcdeviceOSDLock) {
139 rcdeviceOSDLock = true;
141 uint8_t data[60];
142 uint8_t dataLen = 0;
143 for (k = 0; k < MAX_CHARS2UPDATE; k++) {
144 if (screenBuffer[pos] != shadowBuffer[pos]) {
145 shadowBuffer[pos] = screenBuffer[pos];
146 uint8_t x = pos % columnCount;
147 uint8_t y = pos / columnCount;
148 data[dataLen++] = x;
149 data[dataLen++] = y;
150 data[dataLen++] = screenBuffer[pos];
153 if (++pos >= maxScreenSize) {
154 pos = 0;
155 break;
158 runcamDeviceDispWriteChars(osdDevice, data, dataLen);
160 rcdeviceOSDLock = false;
162 #endif
163 return 0;
166 int rcdeviceOSDWriteString(displayPort_t *displayPort, uint8_t x, uint8_t y, const char *buff)
168 UNUSED(displayPort);
169 #if !defined(USE_PARTICLE_DRAW)
170 runcamDeviceDispWriteHorizontalString(osdDevice, x, y, buff);
171 #else
172 for (int xpos = x; *buff && xpos < columnCount; xpos++) {
173 screenBuffer[y * columnCount + xpos] = *buff++;
175 #endif
176 return 0;
179 int rcdeviceOSDWriteChar(displayPort_t *displayPort, uint8_t x, uint8_t y, uint8_t c)
181 UNUSED(displayPort);
182 #if !defined(USE_PARTICLE_DRAW)
183 runcamDeviceDispWriteChar(osdDevice, x, y, c);
184 #else
185 screenBuffer[y * columnCount + x] = c;
186 #endif
188 return 0;
191 int rcdeviceOSDClearScreen(displayPort_t *displayPort)
193 UNUSED(displayPort);
195 #if defined(USE_PARTICLE_DRAW)
196 memset(screenBuffer, 0x20, sizeof(screenBuffer));
197 #else
198 runcamDeviceDispFillRegion(osdDevice, 0, 0, 255, 255, ' ');
199 #endif
201 return 0;
204 bool rcdeviceOSDIsTransferInProgress(const displayPort_t *displayPort)
206 UNUSED(displayPort);
207 return false;
210 bool rcdeviceOSDIsSynced(const displayPort_t *displayPort)
212 UNUSED(displayPort);
213 return true;
216 int rcdeviceOSDHeartbeat(displayPort_t *displayPort)
218 UNUSED(displayPort);
219 return 0;
222 void rcdeviceOSDResync(displayPort_t *displayPort)
224 UNUSED(displayPort);
226 if (video_system == VIDEO_SYSTEM_PAL) {
227 displayPort->rows = RCDEVICE_PROTOCOL_OSD_VIDEO_LINES_PAL;
228 } else {
229 displayPort->rows = RCDEVICE_PROTOCOL_OSD_VIDEO_LINES_NTSC;
232 displayPort->cols = columnCount;
233 maxScreenSize = displayPort->rows * displayPort->cols;
236 uint32_t rcdeviceOSDTxBytesFree(const displayPort_t *displayPort)
238 UNUSED(displayPort);
239 return INT32_MAX;
242 int rcdeviceScreenSize(const displayPort_t *displayPort)
244 return displayPort->rows * displayPort->cols;
247 #endif