Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update configuration APIs #6

Merged
merged 9 commits into from
Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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