Skip to content

Commit 1a58341

Browse files
committed
Handle potential modem TX timeouts
1 parent 80c5d57 commit 1a58341

1 file changed

Lines changed: 57 additions & 47 deletions

File tree

cc1200_modem.go

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ const (
4141
// )
4242

4343
const (
44-
trxIdle = iota
45-
trxRX
46-
trxTX
44+
txIdle = iota
45+
txTX
4746
)
4847

4948
// txTimeout must be greater than this!
@@ -61,14 +60,16 @@ type CC1200Modem struct {
6160
// txSymbols chan float32
6261
s2s SymbolToSample
6362

64-
trxMutex sync.Mutex
65-
trxState int
66-
txTimer *time.Timer
67-
cmdSource chan byte
68-
nRST Line
69-
paEnable Line
70-
boot0 Line
71-
debugLog *os.File
63+
mutex sync.Mutex
64+
txState int // protected by mutex
65+
isCommandWithResponse bool // protected by mutex
66+
txTimer *time.Timer
67+
cmdSource chan byte
68+
nRST Line
69+
paEnable Line
70+
boot0 Line
71+
debugLog *os.File
72+
lastTXData time.Time
7273
}
7374

7475
func NewCC1200Modem(
@@ -89,16 +90,12 @@ func NewCC1200Modem(
8990
})
9091
// Stop it until we transmit
9192
ret.txTimer.Stop()
92-
ret.trxState = trxIdle
93+
ret.txState = txIdle
9394
var err error
9495
fi, err := os.Stat(port)
9596
if err != nil {
9697
return nil, fmt.Errorf("modem stat: %w", err)
9798
}
98-
// err = ret.gpioSetup(nRSTPin, paEnablePin, boot0Pin)
99-
// if err != nil {
100-
// return nil, err
101-
// }
10299
if fi.Mode()&os.ModeSocket == os.ModeSocket {
103100
log.Printf("[DEBUG] Opening emulator")
104101
ret.modem, err = net.Dial("unix", port)
@@ -126,7 +123,6 @@ func NewCC1200Modem(
126123
return nil, fmt.Errorf("rx pipeline setup: %w", err)
127124
}
128125
go ret.processReceivedData(rxSource)
129-
130126
_, err = ret.commandWithResponse([]byte{cmdPing, 2})
131127
if err != nil {
132128
return nil, fmt.Errorf("test PING: %w", err)
@@ -147,9 +143,13 @@ func (m *CC1200Modem) processReceivedData(rxSource chan int8) {
147143
n, err := m.modem.Read(buf)
148144
if n > 0 {
149145
// log.Printf("[DEBUG] processReceivedData read %x, trxState: %d", buf[0], m.trxState.Load())
150-
m.trxMutex.Lock()
151-
if m.trxState == trxRX {
152-
m.trxMutex.Unlock()
146+
m.mutex.Lock()
147+
if m.isCommandWithResponse {
148+
m.mutex.Unlock()
149+
// log.Printf("[DEBUG] processReceivedData cmdSource <- : %x", buf[0])
150+
m.cmdSource <- buf[0]
151+
} else {
152+
m.mutex.Unlock()
153153
select {
154154
case rxSource <- int8(buf[0]):
155155
// sent
@@ -158,10 +158,6 @@ func (m *CC1200Modem) processReceivedData(rxSource chan int8) {
158158
// pipeline is full, so drop it
159159
log.Printf("[DEBUG] processReceivedData dropped rx: %x", buf[0])
160160
}
161-
} else {
162-
m.trxMutex.Unlock()
163-
// log.Printf("[DEBUG] processReceivedData cmdSource <- : %x", buf[0])
164-
m.cmdSource <- buf[0]
165161
}
166162
}
167163
if err != nil {
@@ -360,10 +356,10 @@ func (m *CC1200Modem) TransmitPacket(p Packet) error {
360356
}
361357

362358
func (m *CC1200Modem) TransmitVoiceStream(sd StreamDatagram) error {
363-
m.trxMutex.Lock()
364-
if m.trxState != trxTX {
359+
m.mutex.Lock()
360+
if m.txState != txTX {
365361
// First frame
366-
m.trxMutex.Unlock()
362+
m.mutex.Unlock()
367363
log.Printf("[DEBUG] Sending first frame of stream %x, fn %d, lsf: %v", sd.StreamID, sd.FrameNumber, sd.LSF)
368364
m.stopRX()
369365
time.Sleep(2 * time.Millisecond)
@@ -394,7 +390,7 @@ func (m *CC1200Modem) TransmitVoiceStream(sd StreamDatagram) error {
394390
return fmt.Errorf("failed to send stream frame: %w", err)
395391
}
396392
} else {
397-
m.trxMutex.Unlock()
393+
m.mutex.Unlock()
398394
// log.Printf("[DEBUG] Sending frame of stream %x, fn %d", sd.StreamID, sd.FrameNumber)
399395
syms, err := generateStreamSymbols(sd)
400396
if err != nil {
@@ -485,28 +481,28 @@ func (m *CC1200Modem) startTX() error {
485481
if err != nil {
486482
log.Printf("[DEBUG] Start TX PAEnable: %v", err)
487483
}
488-
m.trxMutex.Lock()
489-
m.trxState = trxTX
490-
m.trxMutex.Unlock()
484+
m.mutex.Lock()
485+
m.txState = txTX
486+
m.mutex.Unlock()
491487
m.txTimer.Reset(txTimeout)
492488
return nil
493489
}
494490

495491
func (m *CC1200Modem) stopTX() {
496492
log.Print("[DEBUG] modem stopTX()")
497-
m.trxMutex.Lock()
493+
m.mutex.Lock()
498494
// Only stop if we've started
499-
if m.trxState == trxTX {
500-
m.trxMutex.Unlock()
495+
if m.txState == txTX {
496+
m.mutex.Unlock()
501497
log.Print("[DEBUG] modem stopping TX")
502498
err := m.setPAEnableGPIO(false)
503499
if err != nil {
504500
log.Printf("[DEBUG] End TX PAEnable: %v", err)
505501
}
506-
m.trxMutex.Lock()
507-
m.trxState = trxIdle
502+
m.mutex.Lock()
503+
m.txState = txIdle
508504
}
509-
m.trxMutex.Unlock()
505+
m.mutex.Unlock()
510506
m.txTimer.Stop()
511507
}
512508

@@ -543,24 +539,26 @@ func (m *CC1200Modem) Start() error {
543539
log.Printf("[DEBUG] Start()")
544540
// Sometimes we don't go into RX, so try stopping first
545541
// m.stopRX()
546-
m.trxMutex.Lock()
547-
m.trxState = trxRX
548-
m.trxMutex.Unlock()
542+
m.mutex.Lock()
543+
m.txState = txIdle
544+
m.mutex.Unlock()
549545
m.clearResponseBuf()
550546
var err error
551547
cmd := []byte{cmdSetRX, 0, 1}
548+
log.Printf("[DEBUG] sending start cmd")
552549
err = m.command(cmd)
553550
if err != nil {
554551
return fmt.Errorf("send set RX start error: %w", err)
555552
}
553+
log.Printf("[DEBUG] end Start()")
556554
return nil
557555
}
558556

559557
func (m *CC1200Modem) stopRX() error {
560-
m.trxMutex.Lock()
558+
m.mutex.Lock()
561559
// Only stop if we've started
562-
if m.trxState == trxRX {
563-
m.trxMutex.Unlock()
560+
if m.txState == txIdle {
561+
m.mutex.Unlock()
564562
log.Printf("[DEBUG] stopRX()")
565563
var err error
566564
cmd := []byte{cmdSetRX, 0, 0}
@@ -570,10 +568,10 @@ func (m *CC1200Modem) stopRX() error {
570568
return fmt.Errorf("send set RX stop: %w", err)
571569
}
572570
m.clearResponseBuf()
573-
m.trxMutex.Lock()
574-
m.trxState = trxIdle
571+
m.mutex.Lock()
572+
m.txState = txIdle
575573
}
576-
m.trxMutex.Unlock()
574+
m.mutex.Unlock()
577575
return nil
578576
}
579577
func (m *CC1200Modem) SetRXFreq(freq uint32) error {
@@ -626,7 +624,13 @@ func (m *CC1200Modem) writeSymbols(symbols []Symbol) error {
626624
log.Printf("[DEBUG] Failed to write to debug log: %v", err)
627625
}
628626
}
627+
if time.Since(m.lastTXData) > 80*time.Millisecond {
628+
// TX may have timed out
629+
log.Printf("[DEBUG] writeSymbols timeout 80ms")
630+
m.startTX()
631+
}
629632
_, err := m.modem.Write(buf)
633+
m.lastTXData = time.Now()
630634
return err
631635
}
632636
func (m *CC1200Modem) commandWithErrResponse(cmd []byte) error {
@@ -671,6 +675,9 @@ func (m *CC1200Modem) command(cmd []byte) error {
671675
func (m *CC1200Modem) commandWithResponse(cmd []byte) ([]byte, error) {
672676
// log.Printf("[DEBUG] commandWithResponse() sending: % 2x", cmd)
673677
m.clearResponseBuf()
678+
m.mutex.Lock()
679+
m.isCommandWithResponse = true
680+
m.mutex.Unlock()
674681
err := m.command(cmd)
675682
if err != nil {
676683
return nil, err
@@ -679,7 +686,10 @@ func (m *CC1200Modem) commandWithResponse(cmd []byte) ([]byte, error) {
679686
if err != nil {
680687
return nil, fmt.Errorf("commandWithResponse(): %w", err)
681688
}
682-
// log.Printf("[DEBUG] commandWithResponse() received: % 2x", resp)
689+
m.mutex.Lock()
690+
m.isCommandWithResponse = false
691+
m.mutex.Unlock()
692+
log.Printf("[DEBUG] commandWithResponse() received: % 2x", resp)
683693
return resp, nil
684694
}
685695

0 commit comments

Comments
 (0)