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 3b68c11
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 173 deletions.
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
179 changes: 120 additions & 59 deletions e220/e220_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,89 +2,150 @@ package e220

import (
"bytes"
"reflect"
"testing"
)

func TestAssignParamsToBytes(t *testing.T) {
func TestParamsToBytes(t *testing.T) {
tests := []struct {
moduleAddr uint16
uartSerialPortRate uint8
airDataRate uint8
subPacket uint8
rssiAmbient uint8
transmitPower uint8
channel uint8
rssiByte uint8
transmitMethod uint8
worCycleSetting uint8
encryptionKey uint16
expected []byte
config Config
expected []byte
}{
// min
{
0x0000,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x0000,
Config{
0x0000,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x0000,
0x00,
},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
},
// arbitary
{
0x55AA,
0x03,
0x0A,
0x02,
0x00,
0x01,
0x14,
0x00,
0x01,
0x03,
0xAA55,
Config{
0x55AA,
0x03,
0x0A,
0x02,
0x00,
0x01,
0x14,
0x00,
0x01,
0x03,
0xAA55,
0x00,
},
[]byte{0x55, 0xAA, 0x6A, 0x81, 0x14, 0x43, 0xAA, 0x55},
},
// max
{
0xFFFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFFFF,
Config{
0xFFFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFFFF,
0x00,
},
[]byte{0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xC7, 0xFF, 0xFF},
},
}

for _, tt := range tests {
got := make([]byte, 8)
paramsToBytes(
tt.config.paramsToBytes(
&got,
tt.moduleAddr,
tt.uartSerialPortRate,
tt.airDataRate,
tt.subPacket,
tt.rssiAmbient,
tt.transmitPower,
tt.channel,
tt.rssiByte,
tt.transmitMethod,
tt.worCycleSetting,
tt.encryptionKey,
)
if !bytes.Equal(got, tt.expected) {
t.Errorf("bytes are not equall: want=%q got=%q", tt.expected, got)
t.Errorf("bytes are not equall: want=%02X got=%02X", tt.expected, got)
}
}
}

func TestBytesToParams(t *testing.T) {
tests := []struct {
expected Config
configBytes []byte
}{
// min
{
Config{
0x0000,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x0000,
0x00,
},
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
},
// arbitary
{
Config{
0x55AA,
0x03,
0x0A,
0x02,
0x00,
0x01,
0x14,
0x00,
0x01,
0x03,
0xAA55,
0xAA,
},
[]byte{0x55, 0xAA, 0x6A, 0x81, 0x14, 0x43, 0xAA, 0x55, 0xAA},
},
// max
{
Config{
0xFFFF,
0x07,
0x1F,
0x03,
0x01,
0x03,
0xFF,
0x01,
0x01,
0x07,
0xFFFF,
0xFF,
},
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
},
}

for _, tt := range tests {
got := Config{}
got.bytesToParams(
tt.configBytes,
)
if !reflect.DeepEqual(got, tt.expected) {
t.Errorf("objects are not equall: want=%02X got=%02X", tt.expected, got)
}
}
}
Loading

0 comments on commit 3b68c11

Please sign in to comment.