Spectrum/BK4829: interlace large sweeps and cut SPI overhead

This commit is contained in:
Armel FAUVEAU committed 2026-04-23 02:27:52 +02:00
1 parent 094896b5f1
commit 65c584ff7d
2 files changed
+155 -40

No files matched your search

+109 -19
View File
@@ -104,6 +104,14 @@ static uint16_t scanReg30 = 0;
// Bidirectional sweep: true = left→right (fStart→fEnd), false = right→left.
static bool scanForward = true;
// Optional interlaced progression for large scans (>128 steps).
// 1 = enabled, 0 = disabled.
#ifndef SPECTRUM_INTERLACE_LARGE_SWEEPS
#define SPECTRUM_INTERLACE_LARGE_SWEEPS 1
#endif
static uint16_t interlaceStride = 1;
static uint16_t interlacePhase = 0;
// Incremental display: one framebuffer page sent per tick instead of a full
// BlitFullScreen burst.
static uint8_t renderPage = 0;
@@ -589,6 +597,16 @@ static void InitScanPosition()
scanInfo.i = 0;
scanInfo.f = GetFStart();
scanForward = true;
#if SPECTRUM_INTERLACE_LARGE_SWEEPS
interlacePhase = 0;
interlaceStride = 1;
if (scanInfo.measurementsCount > ARRAY_SIZE(rssiHistory))
{
interlaceStride =
(scanInfo.measurementsCount + ARRAY_SIZE(rssiHistory) - 1) /
ARRAY_SIZE(rssiHistory);
}
#endif
}
static void InitScan()
@@ -1859,10 +1877,100 @@ static void NextScanStep()
}
}
static bool UseInterlacedSweep()
{
#if SPECTRUM_INTERLACE_LARGE_SWEEPS
return scanInfo.measurementsCount > ARRAY_SIZE(rssiHistory) &&
interlaceStride > 1;
#else
return false;
#endif
}
static bool NextScanStepInterlaced()
{
uint16_t next = scanInfo.i + interlaceStride;
if (next < scanInfo.measurementsCount)
{
scanInfo.i = next;
scanInfo.f += (uint32_t)interlaceStride * scanInfo.scanStep;
return false;
}
for (uint16_t phase = interlacePhase + 1; phase < interlaceStride; ++phase)
{
if (phase < scanInfo.measurementsCount)
{
interlacePhase = phase;
scanInfo.i = phase;
scanInfo.f = GetFStart() + (uint32_t)phase * scanInfo.scanStep;
return false;
}
}
interlacePhase = 0;
return true;
}
static void FinalizeCompletedSweep()
{
if (! (scanInfo.measurementsCount >> 7)) // if (scanInfo.measurementsCount < 128)
memset(&rssiHistory[scanInfo.measurementsCount], 0,
sizeof(rssiHistory) - scanInfo.measurementsCount * sizeof(rssiHistory[0]));
// Auto-adjust dbMax unless the user has overridden it manually.
if (manualDbMaxTimer > 0) {
if (--manualDbMaxTimer == 0)
redrawStatus = true;
} else if (!manualSetFlag) {
int newMax = Rssi2DBm(scanInfo.rssiMax) + 5;
int dbMin = settings.dbMin + 10;
if (newMax < dbMin)
newMax = dbMin;
if (newMax > 10)
newMax = 10;
settings.dbMax = newMax;
}
newScanStart = true;
}
static void UpdateScan()
{
Scan();
#if SPECTRUM_INTERLACE_LARGE_SWEEPS
if (UseInterlacedSweep())
{
bool atEnd = (scanInfo.i + interlaceStride >= scanInfo.measurementsCount);
if (!atEnd)
{
++peak.t;
(void)NextScanStepInterlaced();
return;
}
preventKeypress = false;
UpdatePeakInfo();
if (IsPeakOverLevel())
{
ToggleRX(true);
TuneToPeak();
return;
}
++peak.t;
if (!NextScanStepInterlaced())
return;
FinalizeCompletedSweep();
return;
}
#endif
bool atEnd = scanForward ? (scanInfo.i >= scanInfo.measurementsCount - 1)
: (scanInfo.i <= 1);
@@ -1895,25 +2003,7 @@ static void UpdateScan()
}
// End of backward half-sweep: full round trip done.
if (! (scanInfo.measurementsCount >> 7)) // if (scanInfo.measurementsCount < 128)
memset(&rssiHistory[scanInfo.measurementsCount], 0,
sizeof(rssiHistory) - scanInfo.measurementsCount * sizeof(rssiHistory[0]));
// Auto-adjust dbMax unless the user has overridden it manually.
if (manualDbMaxTimer > 0) {
if (--manualDbMaxTimer == 0)
redrawStatus = true;
} else if (!manualSetFlag) {
int newMax = Rssi2DBm(scanInfo.rssiMax) + 5;
int dbMin = settings.dbMin + 10;
if (newMax < dbMin)
newMax = dbMin;
if (newMax > 10)
newMax = 10;
settings.dbMax = newMax;
}
newScanStart = true;
FinalizeCompletedSweep();
}
static void UpdateStill()
+46 -21
View File
@@ -39,6 +39,16 @@ static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8
static uint16_t gBK4819_GpioOutState;
#define SHORT_DELAY() \
__asm volatile("nop\n nop\n nop\n nop\n nop\n" \
"nop\n nop\n nop\n nop\n nop\n" \
"nop\n nop\n nop\n nop\n nop\n" \
"nop\n nop\n nop\n nop\n nop\n" \
"nop\n nop\n nop\n nop\n nop\n" \
"nop\n nop\n nop\n nop\n nop\n" \
"nop\n nop\n nop\n nop\n nop\n" \
"nop\n nop\n nop\n nop\n nop\n")
bool gRxIdleMode;
static inline void CS_Assert()
@@ -197,63 +207,78 @@ static uint16_t BK4819_ReadU16(void)
uint16_t Value;
SDA_SetDir(false);
SYSTICK_DelayUs(1);
SHORT_DELAY();
Value = 0;
for (i = 0; i < 16; i++)
{
Value <<= 1;
Value |= SDA_ReadInput();
SCL_Set();
SYSTICK_DelayUs(1);
SHORT_DELAY();
SCL_Reset();
SYSTICK_DelayUs(1);
SHORT_DELAY();
}
SDA_SetDir(true);
return Value;
}
static uint16_t reg_30_cache = 0xFFFF;
static uint16_t reg_47_cache = 0xFFFF;
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register)
{
uint16_t Value;
CS_Release();
SCL_Reset();
SYSTICK_DelayUs(1);
SHORT_DELAY();
CS_Assert();
BK4819_WriteU8(Register | 0x80);
Value = BK4819_ReadU16();
CS_Release();
SYSTICK_DelayUs(1);
SHORT_DELAY();
SCL_Set();
SDA_Set();
if (Register == BK4819_REG_30)
reg_30_cache = Value;
else if (Register == BK4819_REG_47)
reg_47_cache = Value;
return Value;
}
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data)
{
if (Register == BK4819_REG_30)
{
if (Data == reg_30_cache)
return;
reg_30_cache = Data;
}
else if (Register == BK4819_REG_47)
{
if (Data == reg_47_cache)
return;
reg_47_cache = Data;
}
CS_Release();
SCL_Reset();
SYSTICK_DelayUs(1);
SHORT_DELAY();
CS_Assert();
BK4819_WriteU8(Register);
SYSTICK_DelayUs(1);
SHORT_DELAY();
BK4819_WriteU16(Data);
SYSTICK_DelayUs(1);
SHORT_DELAY();
CS_Release();
SYSTICK_DelayUs(1);
SHORT_DELAY();
SCL_Set();
SDA_Set();
@@ -271,14 +296,14 @@ void BK4819_WriteU8(uint8_t Data)
else
SDA_Set();
SYSTICK_DelayUs(1);
SHORT_DELAY();
SCL_Set();
SYSTICK_DelayUs(1);
SHORT_DELAY();
Data <<= 1;
SCL_Reset();
SYSTICK_DelayUs(1);
SHORT_DELAY();
}
}
@@ -294,14 +319,14 @@ void BK4819_WriteU16(uint16_t Data)
else
SDA_Set();
SYSTICK_DelayUs(1);
SHORT_DELAY();
SCL_Set();
Data <<= 1;
SYSTICK_DelayUs(1);
SHORT_DELAY();
SCL_Reset();
SYSTICK_DelayUs(1);
SHORT_DELAY();
}
}