mirror of
https://github.com/soypat/lora.git
synced 2026-07-26 07:28:38 +00:00
rename spreadfactor and cleanup type change in sx127x
This commit is contained in:
@@ -22,7 +22,7 @@ type Config struct {
|
||||
// Must be set when working with implicit headers.
|
||||
MaxImplicitPayloadLength uint8
|
||||
CodingRate CodingRate
|
||||
SpreadFactor SpreadFactor // this should probably be called "SpreadingFactor" to be consistent with LoRa terminology
|
||||
SpreadingFactor SpreadingFactor
|
||||
SyncWord uint16 // for new chips sync word is full 16 bits
|
||||
TxPower int8 // Tx Power in dBm.
|
||||
CRC bool
|
||||
@@ -34,9 +34,9 @@ type Config struct {
|
||||
}
|
||||
|
||||
// SymbolPeriod returns the time it takes to transmit a single symbol given the
|
||||
// current configuration parameters. It depends on Spread factor and Bandwidth.
|
||||
// current configuration parameters. It depends on Spreading factor and Bandwidth.
|
||||
func (cfg *Config) SymbolPeriod() time.Duration {
|
||||
T_s := time.Second * time.Duration(cfg.SpreadFactor.ChipsPerSymbol()) /
|
||||
T_s := time.Second * time.Duration(cfg.SpreadingFactor.ChipsPerSymbol()) /
|
||||
time.Duration(cfg.Bandwidth.Hertz())
|
||||
return T_s
|
||||
}
|
||||
@@ -47,7 +47,7 @@ func (cfg *Config) SymbolPeriod() time.Duration {
|
||||
// - CRC presence (presence == longer)
|
||||
// - Header type (explicit == longer)
|
||||
// - Coding rate (proportional)
|
||||
// - Spread factor (inversely proportional)
|
||||
// - Spreading factor (inversely proportional)
|
||||
// - Preamble length (proportional)
|
||||
// - Low data rate optimisation (presence == longer)
|
||||
func (cfg *Config) TimeOnAir(payloadLength int) time.Duration {
|
||||
@@ -58,10 +58,10 @@ func (cfg *Config) TimeOnAir(payloadLength int) time.Duration {
|
||||
ih := int64(cfg.HeaderType)
|
||||
ldr := int64(b2u8(cfg.LDRO))
|
||||
cr := int64(cfg.CodingRate)
|
||||
spread := int64(cfg.SpreadFactor)
|
||||
sf := int64(cfg.SpreadingFactor)
|
||||
// Page 31 SX1276IMLTRT SEMTECH | Alldatasheet.
|
||||
Npayload := 8*int64(payloadLength) - 4*spread + 28 + 16*crc - 20*ih
|
||||
div := 4 * (spread - 2*ldr)
|
||||
Npayload := 8*int64(payloadLength) - 4*sf + 28 + 16*crc - 20*ih
|
||||
div := 4 * (sf - 2*ldr)
|
||||
// Apply Ceil and max with minimal branching.
|
||||
if Npayload < 0 || div <= 0 {
|
||||
Npayload = 0
|
||||
@@ -77,7 +77,7 @@ func (cfg *Config) TimeOnAir(payloadLength int) time.Duration {
|
||||
// time calculated.
|
||||
Npayload += 8 + int64(cfg.PreambleLength) + 5
|
||||
// Calculate LoRa Transmission Parameter Relationship page 28.
|
||||
chipsPerSymbol := cfg.SpreadFactor.ChipsPerSymbol() // chips per symbol.
|
||||
chipsPerSymbol := cfg.SpreadingFactor.ChipsPerSymbol() // chips per symbol.
|
||||
return time.Second * time.Duration(Npayload*int64(chipsPerSymbol)) /
|
||||
time.Duration(cfg.Bandwidth.Hertz())
|
||||
}
|
||||
@@ -110,15 +110,15 @@ const (
|
||||
CR4_8 CodingRate = 4
|
||||
)
|
||||
|
||||
// SpreadFactor defines the number of chips per symbol. Higher spread factors
|
||||
// SpreadingFactor defines the number of chips per symbol. Higher spreading factors
|
||||
// imply longer transmission times but more robust communications.
|
||||
// The number of chips per symbol is 2^SF, so a spread factor of 8 takes twice
|
||||
// as long to transmit a symbol as a spread factor of 7.
|
||||
type SpreadFactor uint8
|
||||
// The number of chips per symbol is 2^SF, so a spreading factor of 8 takes twice
|
||||
// as long to transmit a symbol as a spreading factor of 7.
|
||||
type SpreadingFactor uint8
|
||||
|
||||
// Common spread factors. Decide the number of chips per symbol.
|
||||
// Common spreading factors. Decide the number of chips per symbol.
|
||||
const (
|
||||
SF5 SpreadFactor = iota + 5
|
||||
SF5 SpreadingFactor = iota + 5
|
||||
SF6
|
||||
SF7
|
||||
SF8
|
||||
@@ -130,9 +130,9 @@ const (
|
||||
|
||||
// ChipsPerSymbol returns the number of chips in a symbol. A chip is a subdivision
|
||||
// of a symbol in the frequency domain rather than the time domain, which is why
|
||||
// the units of this value is Hz, not Duration. A chip tells tells where to start
|
||||
// the units of this value is Hz, not Duration. A chip tells where to start
|
||||
// the frequency sweep for a symbol.
|
||||
func (sf SpreadFactor) ChipsPerSymbol() int64 {
|
||||
func (sf SpreadingFactor) ChipsPerSymbol() int64 {
|
||||
return 1 << sf
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ func TestTimeOnAir(t *testing.T) {
|
||||
cfg: lora.Config{
|
||||
Bandwidth: lora.BW125k,
|
||||
Frequency: 915e6,
|
||||
SpreadFactor: lora.SF7,
|
||||
SpreadingFactor: lora.SF7,
|
||||
HeaderType: lora.HeaderExplicit,
|
||||
CodingRate: loraWANCodeRate,
|
||||
CRC: true,
|
||||
@@ -38,7 +38,7 @@ func TestTimeOnAir(t *testing.T) {
|
||||
cfg: lora.Config{
|
||||
Bandwidth: lora.BW500k,
|
||||
Frequency: 915e6,
|
||||
SpreadFactor: lora.SF7,
|
||||
SpreadingFactor: lora.SF7,
|
||||
HeaderType: lora.HeaderExplicit,
|
||||
CodingRate: loraWANCodeRate,
|
||||
CRC: true,
|
||||
|
||||
+16
-13
@@ -81,7 +81,7 @@ type DeviceLoRa struct {
|
||||
func DefaultConfig(freq lora.Frequency) lora.Config {
|
||||
return lora.Config{
|
||||
Frequency: freq,
|
||||
SpreadFactor: lora.SF7,
|
||||
SpreadingFactor: lora.SF7,
|
||||
Bandwidth: lora.BW125k,
|
||||
CodingRate: lora.CR4_5,
|
||||
PreambleLength: 8,
|
||||
@@ -103,7 +103,7 @@ func NewLoRa(bus SPI, cs, reset PinOutput) *DeviceLoRa {
|
||||
}
|
||||
|
||||
var (
|
||||
errBadSpread = errors.New("bad spread factor")
|
||||
errBadSpreadingFactor = errors.New("bad spreading factor")
|
||||
errSF6Implicit = errors.New("SF6 can only be used with implicit header type") // Page 30: Implicit Header Mode.
|
||||
errPreambleTooShort = errors.New("preamble length too short")
|
||||
ErrNotDetected = errors.New("sx127x not detected")
|
||||
@@ -116,6 +116,7 @@ var (
|
||||
ErrCRC = errors.New("crc error")
|
||||
ErrRxTimeout = errors.New("rx timeout")
|
||||
errImplicitPacketTooLarge = errors.New("packet length exceeds MaxImplicitPayloadLength")
|
||||
errSyncWordTooLarge = errors.New("sync word too long")
|
||||
)
|
||||
|
||||
func (d *DeviceLoRa) InitLoRaMode() (err error) {
|
||||
@@ -139,9 +140,9 @@ func (d *DeviceLoRa) InitLoRaMode() (err error) {
|
||||
|
||||
func (d *DeviceLoRa) Configure(cfg lora.Config) (err error) {
|
||||
switch {
|
||||
case cfg.SpreadFactor < lora.SF6 || cfg.SpreadFactor > lora.SF12:
|
||||
err = errBadSpread
|
||||
case cfg.SpreadFactor == lora.SF6 && cfg.HeaderType != lora.HeaderImplicit:
|
||||
case cfg.SpreadingFactor < lora.SF6 || cfg.SpreadingFactor > lora.SF12:
|
||||
err = errBadSpreadingFactor
|
||||
case cfg.SpreadingFactor == lora.SF6 && cfg.HeaderType != lora.HeaderImplicit:
|
||||
err = errSF6Implicit
|
||||
case cfg.PreambleLength < 6:
|
||||
err = errPreambleTooShort
|
||||
@@ -156,6 +157,8 @@ func (d *DeviceLoRa) Configure(cfg lora.Config) (err error) {
|
||||
err = errors.New("MaxImplicitPayloadLength parameter must be set when working with implicit headers")
|
||||
case cfg.TxPower > 20 || cfg.TxPower < -4:
|
||||
err = errors.New("tx power not in operating range -4..20")
|
||||
case cfg.SyncWord > 0xff:
|
||||
err = errSyncWordTooLarge
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -189,7 +192,7 @@ func (d *DeviceLoRa) Configure(cfg lora.Config) (err error) {
|
||||
return err
|
||||
}
|
||||
// TODO(soypat): Use default OCP?
|
||||
err = d.setSyncWord(cfg.SyncWord)
|
||||
err = d.setSyncWord(uint8(cfg.SyncWord))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -197,7 +200,7 @@ func (d *DeviceLoRa) Configure(cfg lora.Config) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = d.setSpreadFactorConsistent(cfg.SpreadFactor)
|
||||
err = d.setSpreadingFactorConsistent(cfg.SpreadingFactor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -706,7 +709,7 @@ func (d *DeviceLoRa) ReadConfig() (cfg lora.Config, err error) {
|
||||
cfg.CodingRate = lora.CodingRate(cfg1>>1) & 0b111
|
||||
cfg.HeaderType = lora.HeaderType(cfg1 & 1)
|
||||
cfg2 := buf[1]
|
||||
cfg.SpreadFactor = lora.SpreadFactor(cfg1 >> 4)
|
||||
cfg.SpreadingFactor = lora.SpreadingFactor(cfg1 >> 4)
|
||||
cfg.CRC = cfg2&0x4 != 0
|
||||
// continuousMode = cfg2&0x8 != 0
|
||||
cfg.PreambleLength = binary.BigEndian.Uint16(buf[3:])
|
||||
@@ -715,7 +718,7 @@ func (d *DeviceLoRa) ReadConfig() (cfg lora.Config, err error) {
|
||||
if err != nil {
|
||||
return cfg, err
|
||||
}
|
||||
cfg.SyncWord = sync
|
||||
cfg.SyncWord = uint16(sync)
|
||||
// Read Frequency.
|
||||
err = d.read(regFRF_MSB, buf[:3])
|
||||
if err != nil {
|
||||
@@ -864,9 +867,9 @@ func (d *DeviceLoRa) setFrequency(freq lora.Frequency) error {
|
||||
return d.Write8(regFRF_LSB, freqReg[2]) // Write LSB last!
|
||||
}
|
||||
|
||||
// setSpreadFactorConsistent sets the spreading factor and closely related parameters
|
||||
// setSpreadingFactorConsistent sets the spreading factor and closely related parameters
|
||||
// including Low Data Rate Optimization, DetectionOptimize, and DetectionThreshold.
|
||||
func (d *DeviceLoRa) setSpreadFactorConsistent(sf lora.SpreadFactor) (err error) {
|
||||
func (d *DeviceLoRa) setSpreadingFactorConsistent(sf lora.SpreadingFactor) (err error) {
|
||||
err = d.setSpreadingFactor(sf)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -889,9 +892,9 @@ func (d *DeviceLoRa) setSpreadFactorConsistent(sf lora.SpreadFactor) (err error)
|
||||
// It does not set parameters closely associated with the spreading factor such as
|
||||
// the Low Data Optimization, the Detection threshold, Detection Optimize and the
|
||||
// Symbol Timeout.
|
||||
func (d *DeviceLoRa) setSpreadingFactor(sf lora.SpreadFactor) error {
|
||||
func (d *DeviceLoRa) setSpreadingFactor(sf lora.SpreadingFactor) error {
|
||||
if sf < 6 || sf > 12 {
|
||||
return errBadSpread
|
||||
return errBadSpreadingFactor
|
||||
}
|
||||
const sfMask = 0b111 << 4
|
||||
return d.writeMasked8(regMODEM_CONFIG_2, sfMask, uint8(sf)<<4)
|
||||
|
||||
+4
-4
@@ -31,7 +31,7 @@ type DeviceLoRa struct {
|
||||
func DefaultConfig(freq lora.Frequency) lora.Config {
|
||||
return lora.Config{
|
||||
Frequency: freq,
|
||||
SpreadFactor: lora.SF9,
|
||||
SpreadingFactor: lora.SF9,
|
||||
Bandwidth: lora.BW1625k,
|
||||
CodingRate: lora.CR4_5,
|
||||
PreambleLength: 12,
|
||||
@@ -90,13 +90,13 @@ func (d *DeviceLoRa) Configure(config lora.Config) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = d.setModulationParamsLoRa(config.SpreadFactor, config.Bandwidth, config.CodingRate)
|
||||
err = d.setModulationParamsLoRa(config.SpreadingFactor, config.Bandwidth, config.CodingRate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// special register setting depending on spreading factor chosen
|
||||
switch config.SpreadFactor {
|
||||
switch config.SpreadingFactor {
|
||||
case lora.SF5, lora.SF6:
|
||||
d.writeRegister(regSpreadingFactorAdditionalConfiguration, []byte{0x1E})
|
||||
case lora.SF7, lora.SF8:
|
||||
@@ -418,7 +418,7 @@ func (d *DeviceLoRa) setBufferBaseAddress(txBase uint8, rxBase uint8) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *DeviceLoRa) setModulationParamsLoRa(spreadingFactor lora.SpreadFactor, bandwidth lora.Frequency, codingRate lora.CodingRate) error {
|
||||
func (d *DeviceLoRa) setModulationParamsLoRa(spreadingFactor lora.SpreadingFactor, bandwidth lora.Frequency, codingRate lora.CodingRate) error {
|
||||
err := d.waitWhileBusy(time.Second)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user