mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-16 21:05:35 +03:00
Tx buffer availability hack to handle slow devices
This commit is contained in:
parent
b42de4f2a4
commit
042096fbb7
7 changed files with 70 additions and 33 deletions
|
@ -67,6 +67,11 @@ int canvasWrite(uint8_t col, uint8_t row, char *string)
|
||||||
return canvasOutput(MSP_CANVAS, (uint8_t *)buf, len + 4);
|
return canvasOutput(MSP_CANVAS, (uint8_t *)buf, len + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t canvasTxRoom()
|
||||||
|
{
|
||||||
|
return mspSerialPushTxRoom();
|
||||||
|
}
|
||||||
|
|
||||||
screenFnVTable_t canvasVTable = {
|
screenFnVTable_t canvasVTable = {
|
||||||
canvasBegin,
|
canvasBegin,
|
||||||
canvasEnd,
|
canvasEnd,
|
||||||
|
@ -74,15 +79,14 @@ screenFnVTable_t canvasVTable = {
|
||||||
canvasWrite,
|
canvasWrite,
|
||||||
canvasHeartBeat,
|
canvasHeartBeat,
|
||||||
NULL,
|
NULL,
|
||||||
|
canvasTxRoom,
|
||||||
};
|
};
|
||||||
|
|
||||||
void canvasCmsInit(displayPort_t *pPort)
|
void canvasCmsInit(displayPort_t *pPort)
|
||||||
{
|
{
|
||||||
pPort->rows = 13;
|
pPort->rows = 13;
|
||||||
pPort->cols = 30;
|
pPort->cols = 30;
|
||||||
pPort->buftime = 23; // = 256/(115200/10)
|
pPort->vTable = &canvasVTable;
|
||||||
pPort->bufsize = 192; // 256 * 3/4 (Be conservative)
|
|
||||||
pPort->VTable = &canvasVTable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void canvasInit()
|
void canvasInit()
|
||||||
|
|
|
@ -107,37 +107,45 @@ int8_t lastCursorPos;
|
||||||
|
|
||||||
void cmsScreenClear(displayPort_t *instance)
|
void cmsScreenClear(displayPort_t *instance)
|
||||||
{
|
{
|
||||||
instance->VTable->clear();
|
instance->vTable->clear();
|
||||||
instance->cleared = true;
|
instance->cleared = true;
|
||||||
lastCursorPos = -1; // XXX Here
|
lastCursorPos = -1; // XXX Here
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmsScreenBegin(displayPort_t *instance)
|
void cmsScreenBegin(displayPort_t *instance)
|
||||||
{
|
{
|
||||||
instance->VTable->begin();
|
instance->vTable->begin();
|
||||||
instance->VTable->clear();
|
instance->vTable->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmsScreenEnd(displayPort_t *instance)
|
void cmsScreenEnd(displayPort_t *instance)
|
||||||
{
|
{
|
||||||
instance->VTable->end();
|
instance->vTable->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmsScreenWrite(displayPort_t *instance, uint8_t x, uint8_t y, char *s)
|
int cmsScreenWrite(displayPort_t *instance, uint8_t x, uint8_t y, char *s)
|
||||||
{
|
{
|
||||||
return instance->VTable->write(x, y, s);
|
return instance->vTable->write(x, y, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmsScreenHeartBeat(displayPort_t *instance)
|
void cmsScreenHeartBeat(displayPort_t *instance)
|
||||||
{
|
{
|
||||||
if (instance->VTable->heartbeat)
|
if (instance->vTable->heartbeat)
|
||||||
instance->VTable->heartbeat();
|
instance->vTable->heartbeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmsScreenResync(displayPort_t *instance)
|
void cmsScreenResync(displayPort_t *instance)
|
||||||
{
|
{
|
||||||
if (instance->VTable->resync)
|
if (instance->vTable->resync)
|
||||||
instance->VTable->resync();
|
instance->vTable->resync();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t cmsScreenTxRoom(displayPort_t *instance)
|
||||||
|
{
|
||||||
|
if (instance->vTable->txroom)
|
||||||
|
return instance->vTable->txroom();
|
||||||
|
else
|
||||||
|
return 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmsScreenInit(displayPort_t *pDisp, cmsDeviceInitFuncPtr cmsDeviceInitFunc)
|
void cmsScreenInit(displayPort_t *pDisp, cmsDeviceInitFuncPtr cmsDeviceInitFunc)
|
||||||
|
@ -377,7 +385,7 @@ void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTime)
|
||||||
static uint8_t pollDenom = 0;
|
static uint8_t pollDenom = 0;
|
||||||
bool drawPolled = (++pollDenom % 8 == 0);
|
bool drawPolled = (++pollDenom % 8 == 0);
|
||||||
|
|
||||||
int16_t cnt = 0;
|
int room = cmsScreenTxRoom(pDisplay);
|
||||||
|
|
||||||
if (!currentMenu)
|
if (!currentMenu)
|
||||||
return;
|
return;
|
||||||
|
@ -404,20 +412,26 @@ void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTime)
|
||||||
currentCursorPos++;
|
currentCursorPos++;
|
||||||
|
|
||||||
if (lastCursorPos >= 0 && currentCursorPos != lastCursorPos) {
|
if (lastCursorPos >= 0 && currentCursorPos != lastCursorPos) {
|
||||||
cnt += cmsScreenWrite(pDisplay, LEFT_MENU_COLUMN, lastCursorPos + top, " ");
|
room -= cmsScreenWrite(pDisplay, LEFT_MENU_COLUMN, lastCursorPos + top, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (room < 30)
|
||||||
|
return;
|
||||||
|
|
||||||
if (lastCursorPos != currentCursorPos) {
|
if (lastCursorPos != currentCursorPos) {
|
||||||
cnt += cmsScreenWrite(pDisplay, LEFT_MENU_COLUMN, currentCursorPos + top, " >");
|
room -= cmsScreenWrite(pDisplay, LEFT_MENU_COLUMN, currentCursorPos + top, " >");
|
||||||
lastCursorPos = currentCursorPos;
|
lastCursorPos = currentCursorPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (room < 30)
|
||||||
|
return;
|
||||||
|
|
||||||
// Print text labels
|
// Print text labels
|
||||||
for (i = 0, p = currentMenu; i < MAX_MENU_ITEMS(pDisplay) && p->type != OME_END; i++, p++) {
|
for (i = 0, p = currentMenu; i < MAX_MENU_ITEMS(pDisplay) && p->type != OME_END; i++, p++) {
|
||||||
if (IS_PRINTLABEL(p)) {
|
if (IS_PRINTLABEL(p)) {
|
||||||
cnt += cmsScreenWrite(pDisplay, LEFT_MENU_COLUMN + 2, i + top, p->text);
|
room -= cmsScreenWrite(pDisplay, LEFT_MENU_COLUMN + 2, i + top, p->text);
|
||||||
CLR_PRINTLABEL(p);
|
CLR_PRINTLABEL(p);
|
||||||
if (cnt > pDisplay->batchsize)
|
if (room < 30)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,12 +439,12 @@ void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTime)
|
||||||
// Print values
|
// Print values
|
||||||
|
|
||||||
// XXX Polled values at latter positions in the list may not be
|
// XXX Polled values at latter positions in the list may not be
|
||||||
// XXX printed if the cnt exceeds batchsize in the middle of the list.
|
// XXX printed if not enough room in the middle of the list.
|
||||||
|
|
||||||
for (i = 0, p = currentMenu; i < MAX_MENU_ITEMS(pDisplay) && p->type != OME_END; i++, p++) {
|
for (i = 0, p = currentMenu; i < MAX_MENU_ITEMS(pDisplay) && p->type != OME_END; i++, p++) {
|
||||||
if (IS_PRINTVALUE(p)) {
|
if (IS_PRINTVALUE(p)) {
|
||||||
cnt += cmsDrawMenuEntry(pDisplay, p, top + i, drawPolled);
|
room -= cmsDrawMenuEntry(pDisplay, p, top + i, drawPolled);
|
||||||
if (cnt > pDisplay->batchsize)
|
if (room < 30)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,12 +508,6 @@ long cmsMenuBack(displayPort_t *pDisplay)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX This should go to device
|
|
||||||
void cmsComputeBatchsize(displayPort_t *pDisplay)
|
|
||||||
{
|
|
||||||
pDisplay->batchsize = (pDisplay->buftime < CMS_UPDATE_INTERVAL) ? pDisplay->bufsize : (pDisplay->bufsize * CMS_UPDATE_INTERVAL) / pDisplay->buftime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX Separation
|
// XXX Separation
|
||||||
void cmsx_FeatureRead(void);
|
void cmsx_FeatureRead(void);
|
||||||
void cmsx_FeatureWriteback(void);
|
void cmsx_FeatureWriteback(void);
|
||||||
|
@ -528,7 +536,6 @@ void cmsMenuOpen(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cmsScreenInit(¤tDisplay, initfunc);
|
cmsScreenInit(¤tDisplay, initfunc);
|
||||||
cmsComputeBatchsize(¤tDisplay);
|
|
||||||
cmsScreenBegin(¤tDisplay);
|
cmsScreenBegin(¤tDisplay);
|
||||||
cmsMenuChange(¤tDisplay, currentMenu);
|
cmsMenuChange(¤tDisplay, currentMenu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ typedef struct screenFnVTable_s {
|
||||||
int (*write)(uint8_t, uint8_t, char *);
|
int (*write)(uint8_t, uint8_t, char *);
|
||||||
int (*heartbeat)(void);
|
int (*heartbeat)(void);
|
||||||
void (*resync)(void);
|
void (*resync)(void);
|
||||||
|
uint16_t (*txroom)(void);
|
||||||
} screenFnVTable_t;
|
} screenFnVTable_t;
|
||||||
|
|
||||||
typedef struct displayPort_s {
|
typedef struct displayPort_s {
|
||||||
|
@ -14,8 +15,7 @@ typedef struct displayPort_s {
|
||||||
uint8_t cols;
|
uint8_t cols;
|
||||||
uint16_t buftime;
|
uint16_t buftime;
|
||||||
uint16_t bufsize;
|
uint16_t bufsize;
|
||||||
uint16_t batchsize; // Computed by CMS
|
screenFnVTable_t *vTable;
|
||||||
screenFnVTable_t *VTable;
|
|
||||||
|
|
||||||
// CMS state
|
// CMS state
|
||||||
bool cleared;
|
bool cleared;
|
||||||
|
|
|
@ -783,6 +783,7 @@ screenFnVTable_t displayCmsVTable = {
|
||||||
displayCmsWrite,
|
displayCmsWrite,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
void displayCmsInit(displayPort_t *pPort)
|
void displayCmsInit(displayPort_t *pPort)
|
||||||
|
@ -791,7 +792,7 @@ void displayCmsInit(displayPort_t *pPort)
|
||||||
pPort->cols = 21;
|
pPort->cols = 21;
|
||||||
pPort->buftime = 1;
|
pPort->buftime = 1;
|
||||||
pPort->bufsize = 50000;
|
pPort->bufsize = 50000;
|
||||||
pPort->VTable = &displayCmsVTable;
|
pPort->vTable = &displayCmsVTable;
|
||||||
}
|
}
|
||||||
#endif // OLEDCMS
|
#endif // OLEDCMS
|
||||||
|
|
||||||
|
|
|
@ -702,6 +702,7 @@ screenFnVTable_t osdVTable = {
|
||||||
osdWrite,
|
osdWrite,
|
||||||
NULL,
|
NULL,
|
||||||
max7456RefreshAll,
|
max7456RefreshAll,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
void osdCmsInit(displayPort_t *pPort)
|
void osdCmsInit(displayPort_t *pPort)
|
||||||
|
@ -709,8 +710,6 @@ void osdCmsInit(displayPort_t *pPort)
|
||||||
shiftdown = masterConfig.osdProfile.row_shiftdown;
|
shiftdown = masterConfig.osdProfile.row_shiftdown;
|
||||||
pPort->rows = max7456GetRowsCount() - shiftdown;
|
pPort->rows = max7456GetRowsCount() - shiftdown;
|
||||||
pPort->cols = 30;
|
pPort->cols = 30;
|
||||||
pPort->buftime = 1; // Very fast
|
pPort->vTable = &osdVTable;
|
||||||
pPort->bufsize = 50000; // Very large
|
|
||||||
pPort->VTable = &osdVTable;
|
|
||||||
}
|
}
|
||||||
#endif // OSD
|
#endif // OSD
|
||||||
|
|
|
@ -246,3 +246,28 @@ void mspSerialPushInit(mspPushCommandFnPtr mspPushCommandFnToUse)
|
||||||
{
|
{
|
||||||
mspPushCommandFn = mspPushCommandFnToUse;
|
mspPushCommandFn = mspPushCommandFnToUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t mspSerialPushTxRoom()
|
||||||
|
{
|
||||||
|
uint16_t minroom = 50000;
|
||||||
|
|
||||||
|
for (uint8_t portIndex = 0; portIndex < MAX_MSP_PORT_COUNT; portIndex++) {
|
||||||
|
mspPort_t * const mspPort = &mspPorts[portIndex];
|
||||||
|
if (!mspPort->port) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX Kludge!!! Avoid zombie VCP port (avoid VCP entirely for now)
|
||||||
|
if (mspPort->port->identifier == SERIAL_PORT_USB_VCP) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t room = mspPort->port->vTable->serialTotalTxFree(mspPort->port);
|
||||||
|
|
||||||
|
if (room < minroom) {
|
||||||
|
minroom = room;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minroom;
|
||||||
|
}
|
||||||
|
|
|
@ -68,3 +68,4 @@ void mspSerialAllocatePorts(void);
|
||||||
void mspSerialReleasePortIfAllocated(struct serialPort_s *serialPort);
|
void mspSerialReleasePortIfAllocated(struct serialPort_s *serialPort);
|
||||||
void mspSerialPushInit(mspPushCommandFnPtr mspPushCommandFn);
|
void mspSerialPushInit(mspPushCommandFnPtr mspPushCommandFn);
|
||||||
void mspSerialPush(uint8_t, uint8_t *, int);
|
void mspSerialPush(uint8_t, uint8_t *, int);
|
||||||
|
uint16_t mspSerialPushTxRoom();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue