mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-16 04:45:24 +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);
|
||||
}
|
||||
|
||||
uint16_t canvasTxRoom()
|
||||
{
|
||||
return mspSerialPushTxRoom();
|
||||
}
|
||||
|
||||
screenFnVTable_t canvasVTable = {
|
||||
canvasBegin,
|
||||
canvasEnd,
|
||||
|
@ -74,15 +79,14 @@ screenFnVTable_t canvasVTable = {
|
|||
canvasWrite,
|
||||
canvasHeartBeat,
|
||||
NULL,
|
||||
canvasTxRoom,
|
||||
};
|
||||
|
||||
void canvasCmsInit(displayPort_t *pPort)
|
||||
{
|
||||
pPort->rows = 13;
|
||||
pPort->cols = 30;
|
||||
pPort->buftime = 23; // = 256/(115200/10)
|
||||
pPort->bufsize = 192; // 256 * 3/4 (Be conservative)
|
||||
pPort->VTable = &canvasVTable;
|
||||
pPort->vTable = &canvasVTable;
|
||||
}
|
||||
|
||||
void canvasInit()
|
||||
|
|
|
@ -107,37 +107,45 @@ int8_t lastCursorPos;
|
|||
|
||||
void cmsScreenClear(displayPort_t *instance)
|
||||
{
|
||||
instance->VTable->clear();
|
||||
instance->vTable->clear();
|
||||
instance->cleared = true;
|
||||
lastCursorPos = -1; // XXX Here
|
||||
}
|
||||
|
||||
void cmsScreenBegin(displayPort_t *instance)
|
||||
{
|
||||
instance->VTable->begin();
|
||||
instance->VTable->clear();
|
||||
instance->vTable->begin();
|
||||
instance->vTable->clear();
|
||||
}
|
||||
|
||||
void cmsScreenEnd(displayPort_t *instance)
|
||||
{
|
||||
instance->VTable->end();
|
||||
instance->vTable->end();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (instance->VTable->heartbeat)
|
||||
instance->VTable->heartbeat();
|
||||
if (instance->vTable->heartbeat)
|
||||
instance->vTable->heartbeat();
|
||||
}
|
||||
|
||||
void cmsScreenResync(displayPort_t *instance)
|
||||
{
|
||||
if (instance->VTable->resync)
|
||||
instance->VTable->resync();
|
||||
if (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)
|
||||
|
@ -377,7 +385,7 @@ void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTime)
|
|||
static uint8_t pollDenom = 0;
|
||||
bool drawPolled = (++pollDenom % 8 == 0);
|
||||
|
||||
int16_t cnt = 0;
|
||||
int room = cmsScreenTxRoom(pDisplay);
|
||||
|
||||
if (!currentMenu)
|
||||
return;
|
||||
|
@ -404,20 +412,26 @@ void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTime)
|
|||
currentCursorPos++;
|
||||
|
||||
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) {
|
||||
cnt += cmsScreenWrite(pDisplay, LEFT_MENU_COLUMN, currentCursorPos + top, " >");
|
||||
room -= cmsScreenWrite(pDisplay, LEFT_MENU_COLUMN, currentCursorPos + top, " >");
|
||||
lastCursorPos = currentCursorPos;
|
||||
}
|
||||
|
||||
if (room < 30)
|
||||
return;
|
||||
|
||||
// Print text labels
|
||||
for (i = 0, p = currentMenu; i < MAX_MENU_ITEMS(pDisplay) && p->type != OME_END; i++, 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);
|
||||
if (cnt > pDisplay->batchsize)
|
||||
if (room < 30)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -425,12 +439,12 @@ void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTime)
|
|||
// Print values
|
||||
|
||||
// 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++) {
|
||||
if (IS_PRINTVALUE(p)) {
|
||||
cnt += cmsDrawMenuEntry(pDisplay, p, top + i, drawPolled);
|
||||
if (cnt > pDisplay->batchsize)
|
||||
room -= cmsDrawMenuEntry(pDisplay, p, top + i, drawPolled);
|
||||
if (room < 30)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -494,12 +508,6 @@ long cmsMenuBack(displayPort_t *pDisplay)
|
|||
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
|
||||
void cmsx_FeatureRead(void);
|
||||
void cmsx_FeatureWriteback(void);
|
||||
|
@ -528,7 +536,6 @@ void cmsMenuOpen(void)
|
|||
return;
|
||||
|
||||
cmsScreenInit(¤tDisplay, initfunc);
|
||||
cmsComputeBatchsize(¤tDisplay);
|
||||
cmsScreenBegin(¤tDisplay);
|
||||
cmsMenuChange(¤tDisplay, currentMenu);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ typedef struct screenFnVTable_s {
|
|||
int (*write)(uint8_t, uint8_t, char *);
|
||||
int (*heartbeat)(void);
|
||||
void (*resync)(void);
|
||||
uint16_t (*txroom)(void);
|
||||
} screenFnVTable_t;
|
||||
|
||||
typedef struct displayPort_s {
|
||||
|
@ -14,8 +15,7 @@ typedef struct displayPort_s {
|
|||
uint8_t cols;
|
||||
uint16_t buftime;
|
||||
uint16_t bufsize;
|
||||
uint16_t batchsize; // Computed by CMS
|
||||
screenFnVTable_t *VTable;
|
||||
screenFnVTable_t *vTable;
|
||||
|
||||
// CMS state
|
||||
bool cleared;
|
||||
|
|
|
@ -783,6 +783,7 @@ screenFnVTable_t displayCmsVTable = {
|
|||
displayCmsWrite,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void displayCmsInit(displayPort_t *pPort)
|
||||
|
@ -791,7 +792,7 @@ void displayCmsInit(displayPort_t *pPort)
|
|||
pPort->cols = 21;
|
||||
pPort->buftime = 1;
|
||||
pPort->bufsize = 50000;
|
||||
pPort->VTable = &displayCmsVTable;
|
||||
pPort->vTable = &displayCmsVTable;
|
||||
}
|
||||
#endif // OLEDCMS
|
||||
|
||||
|
|
|
@ -702,6 +702,7 @@ screenFnVTable_t osdVTable = {
|
|||
osdWrite,
|
||||
NULL,
|
||||
max7456RefreshAll,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void osdCmsInit(displayPort_t *pPort)
|
||||
|
@ -709,8 +710,6 @@ void osdCmsInit(displayPort_t *pPort)
|
|||
shiftdown = masterConfig.osdProfile.row_shiftdown;
|
||||
pPort->rows = max7456GetRowsCount() - shiftdown;
|
||||
pPort->cols = 30;
|
||||
pPort->buftime = 1; // Very fast
|
||||
pPort->bufsize = 50000; // Very large
|
||||
pPort->VTable = &osdVTable;
|
||||
pPort->vTable = &osdVTable;
|
||||
}
|
||||
#endif // OSD
|
||||
|
|
|
@ -246,3 +246,28 @@ void mspSerialPushInit(mspPushCommandFnPtr 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 mspSerialPushInit(mspPushCommandFnPtr mspPushCommandFn);
|
||||
void mspSerialPush(uint8_t, uint8_t *, int);
|
||||
uint16_t mspSerialPushTxRoom();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue