부팅 시 serial packet이 전송되지 않는 버그 수정
This commit is contained in:
@@ -260,9 +260,11 @@ class MainActivity : ComponentActivity() {
|
||||
// This prevents serial interrupts from stealing CPU during the first frame.
|
||||
delay(200)
|
||||
|
||||
vm.txPacketOnce()
|
||||
|
||||
// IMPORTANT:
|
||||
// rxPacketLoop() starts serial open() asynchronously.
|
||||
// Start RX first so txPacketOnce() is less likely to run before FD is ready.
|
||||
vm.rxPacketLoop()
|
||||
vm.txPacketOnce()
|
||||
vm.txPacketLoop()
|
||||
|
||||
Timber.d("System fully operational.")
|
||||
|
||||
@@ -814,24 +814,47 @@ class MainViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun txPacketOnce() {
|
||||
// viewModel init 으로 이동. 필요.
|
||||
// 경고 정보 조회 (주기적 heart beat)
|
||||
// repeatOnLifecycle은 Activity가 포그라운드에 있을 때로 한정지어, 특정 Lifecycle이 Trigger 되었을 때 동작하도록 만드는 block 임.
|
||||
viewModelScope.launch(dispatcherProvider.io) {
|
||||
// txPacketOnce is called during app startup.
|
||||
// Because serial open() is started in rxPacketLoop() asynchronously,
|
||||
// FD can still be -1 here (startup race). Wait briefly before first TX burst.
|
||||
if (!waitUntilSerialReady()) {
|
||||
Timber.e("txPacketOnce skipped: serial port is not ready (fd=%d)", serialPortRepository.getFD())
|
||||
return@launch
|
||||
}
|
||||
|
||||
// tx Version Read
|
||||
txPacket(READ_WRITE.READ, CMD.VERSION, byteArrayOf(0x41.toByte()))
|
||||
// viewModel init 으로 이동. 필요.
|
||||
// 경고 정보 조회 (주기적 heart beat)
|
||||
// repeatOnLifecycle은 Activity가 포그라운드에 있을 때로 한정지어, 특정 Lifecycle이 Trigger 되었을 때 동작하도록 만드는 block 임.
|
||||
|
||||
// tx Q-Switch Write
|
||||
txPacket(READ_WRITE.WRITE, CMD.Q_SWITCH, qSwitch.value)
|
||||
// tx Version Read
|
||||
txPacket(READ_WRITE.READ, CMD.VERSION, byteArrayOf(0x41.toByte()))
|
||||
|
||||
// tx Guide Beam Write
|
||||
txPacket(READ_WRITE.WRITE, CMD.GUIDE_BEAM, GuideBeam(value = getGuideBeamTxValue()))
|
||||
// tx Q-Switch Write
|
||||
txPacket(READ_WRITE.WRITE, CMD.Q_SWITCH, qSwitch.value)
|
||||
|
||||
// tx DCD_GAS Write (DEFAULT VALUE)
|
||||
txPacket(READ_WRITE.WRITE, CMD.DCD_GAS, dcdGas.value.copy(status = 0x50))
|
||||
// tx Guide Beam Write
|
||||
txPacket(READ_WRITE.WRITE, CMD.GUIDE_BEAM, GuideBeam(value = getGuideBeamTxValue()))
|
||||
|
||||
// tx SPRAY_DCD Write (DEFAULT VALUE)
|
||||
txPacket(READ_WRITE.WRITE, CMD.SPRAY_DCD, sprayDcd.value)
|
||||
// tx DCD_GAS Write (DEFAULT VALUE)
|
||||
txPacket(READ_WRITE.WRITE, CMD.DCD_GAS, dcdGas.value.copy(status = 0x50))
|
||||
|
||||
// tx SPRAY_DCD Write (DEFAULT VALUE)
|
||||
txPacket(READ_WRITE.WRITE, CMD.SPRAY_DCD, sprayDcd.value)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun waitUntilSerialReady(
|
||||
timeoutMillis: Long = 2000L,
|
||||
pollIntervalMillis: Long = 20L
|
||||
): Boolean {
|
||||
// Poll FD until open() completes, with a bounded timeout to avoid blocking forever.
|
||||
val start = System.currentTimeMillis()
|
||||
while (System.currentTimeMillis() - start < timeoutMillis) {
|
||||
if (serialPortRepository.getFD() != -1) return true
|
||||
delay(pollIntervalMillis)
|
||||
}
|
||||
return serialPortRepository.getFD() != -1
|
||||
}
|
||||
|
||||
// Guide Beam step mapping (0~10)
|
||||
|
||||
Reference in New Issue
Block a user