Skip to content

Commit

Permalink
update configuration APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
akif999 committed Feb 13, 2023
1 parent 4545d3a commit 0eff0c5
Show file tree
Hide file tree
Showing 5 changed files with 363 additions and 173 deletions.
108 changes: 108 additions & 0 deletions e220/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package e220

import "fmt"

type Config struct {
ModuleAddr uint16
UartSerialPortRate uint8
AirDataRate uint8
SubPacket uint8
RssiAmbient uint8
TransmitPower uint8
Channel uint8
RssiByte uint8
TransmitMethod uint8
WorCycleSetting uint8
EncryptionKey uint16
Version uint8
}

func (c *Config) paramsToBytes(
bytes *[]byte,
) error {
// byte [8] is read only
if len(*bytes) < E220RegisterLength-1 {
return fmt.Errorf("bytes must be greater than or equal to %d: got=%d", E220RegisterLength-1, (*bytes))
}
(*bytes)[0] = byte((c.ModuleAddr & 0xFF00) >> 8)
(*bytes)[1] = byte((c.ModuleAddr & 0x00FF) >> 0)
(*bytes)[2] = byte(((c.UartSerialPortRate & 0x07) << 5) | (c.AirDataRate & 0x1F))
reserved := byte(0b000)
(*bytes)[3] = byte(((c.SubPacket & 0x03) << 6) | ((c.RssiAmbient & 0x01) << 5) | ((reserved & 0x07) << 2) | (c.TransmitPower & 0x03))
(*bytes)[4] = byte(c.Channel)
reserved = byte(0b000)
(*bytes)[5] = byte(((c.RssiByte & 0x01) << 7) | ((c.TransmitMethod & 0x01) << 6) | ((reserved & 0x07) << 3) | (c.WorCycleSetting & 0x07))
(*bytes)[6] = byte((c.EncryptionKey & 0xFF00) >> 8)
(*bytes)[7] = byte((c.EncryptionKey & 0x00FF) >> 0)

return nil
}

func (c *Config) bytesToParams(bytes []byte) error {
if len(bytes) < E220RegisterLength {
return fmt.Errorf("bytes must be greater than or equal to %d: got=%d", E220RegisterLength, (bytes))
}
c.ModuleAddr = uint16((uint16(bytes[0]) << 8) | (uint16(bytes[1]) << 0))
c.UartSerialPortRate = uint8((bytes[2] & 0xE0) >> 5)
c.AirDataRate = uint8((bytes[2] & 0x1F) >> 0)
c.SubPacket = uint8((bytes[3] & 0xC0) >> 6)
c.RssiAmbient = uint8((bytes[3] & 0x20) >> 5)
c.TransmitPower = uint8((bytes[3] & 0x03) >> 0)
c.Channel = bytes[4]
c.RssiByte = uint8((bytes[5] & 0x80) >> 7)
c.TransmitMethod = uint8((bytes[5] & 0x40) >> 6)
c.WorCycleSetting = uint8((bytes[5] & 0x07) >> 0)
c.EncryptionKey = uint16((uint16(bytes[6]) << 8) | (uint16(bytes[7]) << 0))
c.Version = bytes[8]

return nil
}

func (c *Config) String() string {
moduleAddr := fmt.Sprintf("ModuleAddr0x%04X", c.ModuleAddr)
channel := fmt.Sprintf("Channel%02d", c.Channel)
uartSerialPortRate, ok := uartSerialPortRateStrings[c.UartSerialPortRate]
if !ok {
uartSerialPortRate = "UartSerialPortRate: invalid parameter"
}
airDataRate, ok := airDataRateStrings[c.AirDataRate]
if !ok {
airDataRate = "AirDataRate: invalid parameter"
}
subPacket, ok := subPacketStrings[c.SubPacket]
if !ok {
subPacket = "SubPacket: invalid parameter"
}
rssiAmbient, ok := rssiAmbientString[c.RssiAmbient]
if !ok {
rssiAmbient = "RSSIAmbient: invalid parameter"
}
transmitPower, ok := transmitPowerString[c.TransmitPower]
if !ok {
transmitPower = "TransmitPower: invalid parameter"
}
rssiByte, ok := rssiByteString[c.RssiByte]
if !ok {
rssiByte = "RSSIByte: invalid parameter"
}
transmitMethod, ok := transmitMethodString[c.TransmitMethod]
if !ok {
transmitMethod = "TransmitMethod: invalid parameter"
}
worCycleSetting, ok := worCycleSettingString[c.WorCycleSetting]
if !ok {
worCycleSetting = "WorCycleSetting: invalid parameter"
}
encryptionKey := fmt.Sprintf("EncryptionKey0x%04X", c.ModuleAddr)
if !ok {
worCycleSetting = "WorCycleSetting: invalid parameter"
}
version := fmt.Sprintf("Version0x%02X", c.Version)

return fmt.Sprintf(
"%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s",
moduleAddr, channel, uartSerialPortRate, airDataRate,
subPacket, rssiAmbient, transmitPower, rssiByte,
transmitMethod, worCycleSetting, encryptionKey, version,
)
}
127 changes: 45 additions & 82 deletions e220/e220.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (d *Device) ReadRegister(startAddr uint8, length uint8) ([]byte, error) {
return nil, fmt.Errorf("unexpected response: %X", response)
}

return response, nil
return response[3:], nil
}

// WriteRegister writes the register value from startAddr to the value of params
Expand Down Expand Up @@ -204,46 +204,38 @@ func (d *Device) writeRegister(cmd, startAddr, length uint8, params []byte) ([]b
}
runtime.Gosched()
}
// Wait for a while because the next register access
// cannot be received immediately after register access
time.Sleep(50 * time.Millisecond)

return d.payload[:readIndex], nil
}

// WriteConfig writes configuration values to E220
func (d *Device) WriteConfig(
moduleAddr uint16,
uartSerialPortRate uint8,
airDataRate uint8,
subPacket uint8,
rssiAmbient uint8,
transmitPower uint8,
channel uint8,
rssiByte uint8,
transmitMethod uint8,
worCycleSetting uint8,
encryptionKey uint16,
) error {
if uartSerialPortRate > UartSerialPortRate115200Bps {
return fmt.Errorf("uartSerialPortRate must be less than or equal to %d, got=%d", UartSerialPortRate115200Bps, uartSerialPortRate)
func (d *Device) WriteConfig(cfg Config) error {
if cfg.UartSerialPortRate > UartSerialPortRate115200Bps {
return fmt.Errorf("uartSerialPortRate must be less than or equal to %d, got=%d", UartSerialPortRate115200Bps, cfg.UartSerialPortRate)
}
if airDataRate > AirDataRate2148Bps {
return fmt.Errorf("airDataRate must be less than or equal to %d, got=%d", AirDataRate2148Bps, airDataRate)
if cfg.AirDataRate > AirDataRate2148Bps {
return fmt.Errorf("airDataRate must be less than or equal to %d, got=%d", AirDataRate2148Bps, cfg.AirDataRate)
}
if subPacket > SubPacket32Bytes {
return fmt.Errorf("subPacket must be less than or equal to %d, got=%d", SubPacket32Bytes, subPacket)
if cfg.SubPacket > SubPacket32Bytes {
return fmt.Errorf("subPacket must be less than or equal to %d, got=%d", SubPacket32Bytes, cfg.SubPacket)
}
if rssiAmbient > RSSIAmbientEnable {
return fmt.Errorf("rssiAmbient must be less than or equal to %d, got=%d", RSSIAmbientEnable, rssiAmbient)
if cfg.RssiAmbient > RSSIAmbientEnable {
return fmt.Errorf("rssiAmbient must be less than or equal to %d, got=%d", RSSIAmbientEnable, cfg.RssiAmbient)
}
if transmitPower > TransmitPower0Dbm {
return fmt.Errorf("transmitPower must be less than or equal to %d, got=%d", TransmitPower0Dbm, transmitPower)
if cfg.TransmitPower > TransmitPower0Dbm {
return fmt.Errorf("transmitPower must be less than or equal to %d, got=%d", TransmitPower0Dbm, cfg.TransmitPower)
}
if rssiByte > RSSIByteEnable {
return fmt.Errorf("rssiByte must be less than or equal to %d, got=%d", RSSIByteEnable, rssiByte)
if cfg.RssiByte > RSSIByteEnable {
return fmt.Errorf("rssiByte must be less than or equal to %d, got=%d", RSSIByteEnable, cfg.RssiByte)
}
if transmitMethod > TransmitMethodFixed {
return fmt.Errorf("transmitMethod must be less than or equal to %d, got=%d", TransmitMethodFixed, transmitMethod)
if cfg.TransmitMethod > TransmitMethodFixed {
return fmt.Errorf("transmitMethod must be less than or equal to %d, got=%d", TransmitMethodFixed, cfg.TransmitMethod)
}
if worCycleSetting > WorCycleSetting4000ms {
return fmt.Errorf("worCycleSetting must be less than or equal to %d, got=%d", WorCycleSetting4000ms, transmitMethod)
if cfg.WorCycleSetting > WorCycleSetting4000ms {
return fmt.Errorf("worCycleSetting must be less than or equal to %d, got=%d", WorCycleSetting4000ms, cfg.TransmitMethod)
}

var bwTbl = map[uint8]uint16{
Expand All @@ -267,71 +259,42 @@ func (d *Device) WriteConfig(
AirDataRate2148Bps: 500,
}

switch bwTbl[airDataRate] {
switch bwTbl[cfg.AirDataRate] {
case 125:
if channel > 37 {
return fmt.Errorf("if band width is %dKHz, channel must be less than or equal to %d, got=%d", 125, 37, channel)
if cfg.Channel > 37 {
return fmt.Errorf("if band width is %dKHz, cfg.Channel must be less than or equal to %d, got=%d", 125, 37, cfg.Channel)
}
case 250:
if channel > 36 {
return fmt.Errorf("if band width is %dKHz, channel must be less than or equal to %d, got=%d", 250, 36, channel)
if cfg.Channel > 36 {
return fmt.Errorf("if band width is %dKHz, cfg.Channel must be less than or equal to %d, got=%d", 250, 36, cfg.Channel)
}
case 500:
if channel > 30 {
return fmt.Errorf("if band width is %dKHz, channel must be less than or equal to %d, got=%d", 500, 30, channel)
if cfg.Channel > 30 {
return fmt.Errorf("if band width is %dKHz, cfg.Channel must be less than or equal to %d, got=%d", 500, 30, cfg.Channel)
}
default:
return fmt.Errorf("invalid band width value: %d", bwTbl[airDataRate])
}

paramsToBytes(
&d.parameters,
moduleAddr,
uartSerialPortRate,
airDataRate,
subPacket,
rssiAmbient,
transmitPower,
channel,
rssiByte,
transmitMethod,
worCycleSetting,
encryptionKey,
)
return fmt.Errorf("invalid band width value: %d", bwTbl[cfg.AirDataRate])
}

return d.WriteRegister(0x00, d.parameters)
}
cfg.paramsToBytes(&d.parameters)

func paramsToBytes(
bytes *[]byte,
moduleAddr uint16,
uartSerialPortRate uint8,
airDataRate uint8,
subPacket uint8,
rssiAmbient uint8,
transmitPower uint8,
channel uint8,
rssiByte uint8,
transmitMethod uint8,
worCycleSetting uint8,
encryptionKey uint16,
) {
(*bytes)[0] = byte((moduleAddr & 0xFF00) >> 8)
(*bytes)[1] = byte((moduleAddr & 0x00FF) >> 0)
(*bytes)[2] = byte(((uartSerialPortRate & 0x07) << 5) | (airDataRate & 0x1F))
reserved := byte(0b000)
(*bytes)[3] = byte(((subPacket & 0x03) << 6) | ((rssiAmbient & 0x01) << 5) | ((reserved & 0x07) << 2) | (transmitPower & 0x03))
(*bytes)[4] = byte(channel)
reserved = byte(0b000)
(*bytes)[5] = byte(((rssiByte & 0x01) << 7) | ((transmitMethod & 0x01) << 6) | ((reserved & 0x07) << 3) | (worCycleSetting & 0x07))
(*bytes)[6] = byte((encryptionKey & 0xFF00) >> 8)
(*bytes)[7] = byte((encryptionKey & 0x00FF) >> 0)
return d.WriteRegister(0x00, d.parameters)
}

// ReadConfig reads configuration values from E220
func (d *Device) ReadConfig() ([]byte, error) {
func (d *Device) ReadConfig() (*Config, error) {
// "+1" is read only register (addr = 0x08)
return d.ReadRegister(0x00, writingRegisterSize+1)
registerBytes, err := d.ReadRegister(0x00, writingRegisterSize+1)
if err != nil {
return nil, err
}
config := Config{}
err = config.bytesToParams(registerBytes)
if err != nil {
return nil, err
}

return &config, nil
}

// IsReady returns whether the device is ready for new commands.
Expand Down
Loading

0 comments on commit 0eff0c5

Please sign in to comment.