mirror of
https://github.com/soypat/lora.git
synced 2026-08-18 03:23:55 +00:00
first commit
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package lora
|
||||
|
||||
import "time"
|
||||
|
||||
type Config struct {
|
||||
// Bandwidth relates to data rate of communication. Double the bandwidth means
|
||||
// double the data rate, which implies faster communications and less energy usage.
|
||||
Bandwidth Frequency
|
||||
Frequency Frequency
|
||||
// Length of the preamble preceding the header. Can be arbitrarily long.
|
||||
// Longer preambles ensure more robust communications but can lead to congestion.
|
||||
//
|
||||
// Note: The preamble length on a receiver should be configured equal-to or greater
|
||||
// than the expected packet preamble length on the SX1278.
|
||||
PreambleLength uint16
|
||||
HeaderType HeaderType
|
||||
CodingRate CodingRate
|
||||
SpreadFactor SpreadFactor
|
||||
SyncWord uint8
|
||||
TxPower int8 // Tx Power in dBm.
|
||||
CRC bool
|
||||
// Low data rate optimisation flag. The use of this flag is mandated when
|
||||
// the symbol duration exceeds 16ms. Increases reliability at high spreading factors.
|
||||
LDRO bool
|
||||
IQMode uint8
|
||||
}
|
||||
|
||||
func (cfg *Config) TimeOnAir(payloadLength int) time.Duration {
|
||||
if cfg.Bandwidth == 0 {
|
||||
return 0
|
||||
}
|
||||
crc := int64(b2u8(cfg.CRC))
|
||||
ih := int64(cfg.HeaderType)
|
||||
ldr := int64(b2u8(cfg.LDRO))
|
||||
cr := int64(cfg.CodingRate)
|
||||
spread := int64(cfg.SpreadFactor)
|
||||
// Page 31 SX1276IMLTRT SEMTECH | Alldatasheet.
|
||||
Npayload := 8*int64(payloadLength) - 4*spread + 28 + 16*crc - 20*ih
|
||||
div := 4 * (spread - 2*ldr)
|
||||
// Apply Ceil and max with minimal branching.
|
||||
if Npayload < 0 || div <= 0 {
|
||||
Npayload = 0
|
||||
} else if Npayload%div == 0 {
|
||||
Npayload /= div
|
||||
Npayload *= (cr + 4)
|
||||
} else {
|
||||
Npayload /= div
|
||||
Npayload++
|
||||
Npayload *= (cr + 4)
|
||||
}
|
||||
Npayload += 8 + int64(cfg.PreambleLength) + 5 // Says 4.25 in manual but we round up.
|
||||
// Calculate LoRa Transmission Parameter Relationship page 28.
|
||||
Ts_us := 1000_000 * cfg.SpreadFactor.ChipsPerSymbol() / cfg.Bandwidth.Hertz()
|
||||
return time.Microsecond * (time.Duration(Npayload * Ts_us))
|
||||
}
|
||||
|
||||
type HeaderType uint8
|
||||
|
||||
const (
|
||||
HeaderExplicit HeaderType = 0
|
||||
HeaderImplicit HeaderType = 1
|
||||
)
|
||||
|
||||
type CodingRate uint8
|
||||
|
||||
const (
|
||||
CR4_5 CodingRate = 1
|
||||
CR4_6 CodingRate = 2
|
||||
CR4_7 CodingRate = 3
|
||||
CR4_8 CodingRate = 4
|
||||
)
|
||||
|
||||
type SpreadFactor uint8
|
||||
|
||||
const (
|
||||
SF6 SpreadFactor = iota + 6
|
||||
SF7
|
||||
SF8
|
||||
SF9
|
||||
SF10
|
||||
SF11
|
||||
SF12
|
||||
)
|
||||
|
||||
func (sf SpreadFactor) ChipsPerSymbol() int64 {
|
||||
return 1 << sf
|
||||
}
|
||||
|
||||
type Frequency int64
|
||||
|
||||
func (f Frequency) Hertz() int64 { return int64(f) }
|
||||
|
||||
const (
|
||||
Hertz Frequency = 1
|
||||
KiloHertz Frequency = 1000 * Hertz
|
||||
MegaHertz Frequency = 1000 * KiloHertz
|
||||
)
|
||||
|
||||
// Common LoRa bandwidths
|
||||
const (
|
||||
BW125k = 125 * KiloHertz
|
||||
BW250k = 250 * KiloHertz
|
||||
BW500k = 500 * KiloHertz
|
||||
)
|
||||
|
||||
// Common LoRa frequencies
|
||||
const (
|
||||
// 433.05MHz Low limit medical, scientific and industrial band.
|
||||
Freq433_0M = 433050000 * Hertz
|
||||
// 434.8MHz High limit medical, scientific and industrial band.
|
||||
Freq434_8M = 434790000 * Hertz
|
||||
Freq868_1M = 868100000 * Hertz
|
||||
Freq868_5M = 868500000 * Hertz
|
||||
Freq916_8M = 916800000 * Hertz
|
||||
Freq923_3M = 923300000 * Hertz
|
||||
)
|
||||
|
||||
func max[T ~int | ~int64 | ~uint8](a, b T) T {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func b2u8(b bool) uint8 {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user