2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
25 #ifdef USE_MSP_DISPLAYPORT
27 #include "common/utils.h"
29 #include "config/parameter_group.h"
30 #include "config/parameter_group_ids.h"
32 #include "drivers/display.h"
34 #include "fc/fc_msp.h"
36 #include "io/displayport_msp.h"
38 #include "msp/msp_protocol.h"
39 #include "msp/msp_serial.h"
41 #define MSP_OSD_MAX_STRING_LENGTH 30
43 static displayPort_t mspDisplayPort
;
45 extern uint8_t cliMode
;
47 static int output(displayPort_t
*displayPort
, uint8_t cmd
, uint8_t *buf
, int len
)
51 // FIXME There should be no dependency on the CLI but mspSerialPush doesn't check for cli mode, and can't because it also shouldn't have a dependency on the CLI.
55 return mspSerialPush(cmd
, buf
, len
);
58 static int heartbeat(displayPort_t
*displayPort
)
60 uint8_t subcmd
[] = { 0 };
62 // heartbeat is used to:
63 // a) ensure display is not released by MW OSD software
64 // b) prevent OSD Slave boards from displaying a 'disconnected' status.
65 return output(displayPort
, MSP_DISPLAYPORT
, subcmd
, sizeof(subcmd
));
68 static int grab(displayPort_t
*displayPort
)
70 return heartbeat(displayPort
);
73 static int release(displayPort_t
*displayPort
)
75 uint8_t subcmd
[] = { MSP_DP_RELEASE
};
77 return output(displayPort
, MSP_DISPLAYPORT
, subcmd
, sizeof(subcmd
));
80 static int clearScreen(displayPort_t
*displayPort
)
82 uint8_t subcmd
[] = { MSP_DP_CLEAR_SCREEN
};
84 return output(displayPort
, MSP_DISPLAYPORT
, subcmd
, sizeof(subcmd
));
87 static int drawScreen(displayPort_t
*displayPort
)
89 uint8_t subcmd
[] = { MSP_DP_DRAW_SCREEN
};
90 return output(displayPort
, MSP_DISPLAYPORT
, subcmd
, sizeof(subcmd
));
93 static int screenSize(const displayPort_t
*displayPort
)
95 return displayPort
->rows
* displayPort
->cols
;
98 static int writeString(displayPort_t
*displayPort
, uint8_t col
, uint8_t row
, const char *string
, textAttributes_t attr
)
102 uint8_t buf
[MSP_OSD_MAX_STRING_LENGTH
+ 4];
104 int len
= strlen(string
);
105 if (len
>= MSP_OSD_MAX_STRING_LENGTH
) {
106 len
= MSP_OSD_MAX_STRING_LENGTH
;
109 buf
[0] = MSP_DP_WRITE_STRING
;
113 memcpy(&buf
[4], string
, len
);
115 return output(displayPort
, MSP_DISPLAYPORT
, buf
, len
+ 4);
118 static int writeChar(displayPort_t
*displayPort
, uint8_t col
, uint8_t row
, uint16_t c
, textAttributes_t attr
)
124 return writeString(displayPort
, col
, row
, buf
, attr
); //!!TODO - check if there is a direct MSP command to do this
127 static bool isTransferInProgress(const displayPort_t
*displayPort
)
133 static void resync(displayPort_t
*displayPort
)
135 displayPort
->rows
= 13;
136 displayPort
->cols
= 30;
139 static uint32_t txBytesFree(const displayPort_t
*displayPort
)
142 // Should be fixed if we ever get this thing to work
146 static const displayPortVTable_t mspDisplayPortVTable
= {
149 .clearScreen
= clearScreen
,
150 .drawScreen
= drawScreen
,
151 .screenSize
= screenSize
,
152 .writeString
= writeString
,
153 .writeChar
= writeChar
,
155 .isTransferInProgress
= isTransferInProgress
,
156 .heartbeat
= heartbeat
,
158 .txBytesFree
= txBytesFree
,
159 .supportedTextAttributes
= NULL
,
162 displayPort_t
*displayPortMspInit(void)
164 displayInit(&mspDisplayPort
, &mspDisplayPortVTable
);
165 resync(&mspDisplayPort
);
166 mspDisplayPort
.displayPortType
= "MSP";
167 return &mspDisplayPort
;
170 #endif // USE_MSP_DISPLAYPORT