Skip to content

Commit 2992df4

Browse files
committed
libs/unit/lora_e220_jp.py: Reduce memory destruction.
Signed-off-by: lbuque <[email protected]>
1 parent d68cf8c commit 2992df4

File tree

1 file changed

+127
-113
lines changed

1 file changed

+127
-113
lines changed

m5stack/libs/unit/lora_e220_jp.py

Lines changed: 127 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -11,136 +11,145 @@
1111
import machine
1212
import time
1313
import _thread
14+
import struct
1415

1516

16-
class Def:
17+
class LoRaE220JPUnit:
1718
# Baud Rate Values
18-
BAUD_1200 = 0b000
19-
BAUD_2400 = 0b001
20-
BAUD_4800 = 0b010
21-
BAUD_9600 = 0b011
22-
BAUD_19200 = 0b100
23-
BAUD_38400 = 0b101
24-
BAUD_57600 = 0b110
25-
BAUD_115200 = 0b111
19+
BAUD_1200 = 0b0000_0000
20+
BAUD_2400 = 0b0010_0000
21+
BAUD_4800 = 0b0100_0000
22+
BAUD_9600 = 0b0110_0000
23+
BAUD_19200 = 0b1000_0000
24+
BAUD_38400 = 0b1010_0000
25+
BAUD_57600 = 0b1100_0000
26+
BAUD_115200 = 0b1110_0000
2627

2728
# Data Rate Values
28-
BW125K_SF5 = 0b00000
29-
BW125K_SF6 = 0b00100
30-
BW125K_SF7 = 0b01000
31-
BW125K_SF8 = 0b01100
32-
BW125K_SF9 = 0b10000
33-
BW250K_SF5 = 0b00001
34-
BW250K_SF6 = 0b00101
35-
BW250K_SF7 = 0b01001
36-
BW250K_SF8 = 0b01101
37-
BW250K_SF9 = 0b10001
38-
BW250K_SF10 = 0b10101
39-
BW500K_SF5 = 0b00010
40-
BW500K_SF6 = 0b00110
41-
BW500K_SF7 = 0b01010
42-
BW500K_SF8 = 0b01110
43-
BW500K_SF9 = 0b10010
44-
BW500K_SF10 = 0b10110
45-
BW500K_SF11 = 0b11010
29+
BW125K_SF5 = 0b0000_0000
30+
BW125K_SF6 = 0b0000_0100
31+
BW125K_SF7 = 0b0000_1000
32+
BW125K_SF8 = 0b0000_1100
33+
BW125K_SF9 = 0b0001_0000
34+
BW250K_SF5 = 0b0000_0001
35+
BW250K_SF6 = 0b0000_0101
36+
BW250K_SF7 = 0b0000_1001
37+
BW250K_SF8 = 0b0000_1101
38+
BW250K_SF9 = 0b0001_0001
39+
BW250K_SF10 = 0b0001_0101
40+
BW500K_SF5 = 0b0000_0010
41+
BW500K_SF6 = 0b0000_0110
42+
BW500K_SF7 = 0b0000_1010
43+
BW500K_SF8 = 0b0000_1110
44+
BW500K_SF9 = 0b0001_0010
45+
BW500K_SF10 = 0b0001_0110
46+
BW500K_SF11 = 0b0001_1010
4647

4748
# Subpacket Size Values
48-
SUBPACKET_200_BYTE = 0b00
49-
SUBPACKET_128_BYTE = 0b01
50-
SUBPACKET_64_BYTE = 0b10
51-
SUBPACKET_32_BYTE = 0b11
49+
SUBPACKET_200_BYTE = 0b0000_0000
50+
SUBPACKET_128_BYTE = 0b0100_0000
51+
SUBPACKET_64_BYTE = 0b1000_0000
52+
SUBPACKET_32_BYTE = 0b1100_0000
5253

5354
# RSSI Ambient Noise Flag Values
54-
RSSI_AMBIENT_NOISE_ENABLE = 0b1
55-
RSSI_AMBIENT_NOISE_DISABLE = 0b0
55+
RSSI_AMBIENT_NOISE_ENABLE = 0b0010_0000
56+
RSSI_AMBIENT_NOISE_DISABLE = 0b0000_0000
5657

5758
# Transmitting Power Values
58-
TX_POWER_13dBm = 0b01
59-
TX_POWER_7dBm = 0b10
60-
TX_POWER_0dBm = 0b11
59+
TX_POWER_13dBm = 0b0000_0000
60+
TX_POWER_12dBm = 0b0000_0001
61+
TX_POWER_7dBm = 0b0000_0010
62+
TX_POWER_0dBm = 0b0000_0011
6163

6264
# RSSI Byte Flag Values
63-
RSSI_BYTE_ENABLE = 0b1
64-
RSSI_BYTE_DISABLE = 0b0
65+
RSSI_BYTE_ENABLE = 0b1000_0000
66+
RSSI_BYTE_DISABLE = 0b0000_0000
6567

6668
# Transmission Method Type Values
67-
UART_TT_MODE = 0b0
68-
UART_P2P_MODE = 0b1
69+
UART_TT_MODE = 0b0000_0000
70+
UART_P2P_MODE = 0b0100_0000
6971

7072
# LBT Flag Values
71-
LBT_ENABLE = 0b1
72-
LBT_DISABLE = 0b0
73+
# LBT_ENABLE = 0b0001_0000
74+
# LBT_DISABLE = 0b0000_0000
7375

7476
# WOR Cycle Values
75-
WOR_500MS = 0b000
76-
WOR_1000MS = 0b001
77-
WOR_1500MS = 0b010
78-
WOR_2000MS = 0b011
79-
77+
WOR_500MS = 0b0000_0000
78+
WOR_1000MS = 0b0000_0001
79+
WOR_1500MS = 0b0000_0010
80+
WOR_2000MS = 0b0000_0011
81+
WOR_2500MS = 0b0000_0100
82+
WOR_3000MS = 0b0000_0101
8083

81-
class LoRaE220JPUnit:
8284
def __init__(self, port, port_id=1) -> None:
8385
# print('Port: ', port)
8486
self.uart = machine.UART(port_id, tx=port[1], rx=port[0])
8587
self.uart.init(9600, bits=0, parity=None, stop=1, rxbuf=1024)
8688
self.recv_running = False
8789
self.receive_callback = None
90+
self._TXD_BUFFER = bytearray(200)
91+
self._RXD_BUFFER = bytearray(200)
92+
self.max_len = 200
93+
self.rssi_byte_flag = self.RSSI_BYTE_DISABLE
8894

89-
def _conf_range(self, target, min, max):
95+
def _conf_range(self, target, min, max) -> bool:
9096
return min <= target <= max
9197

9298
def setup(
9399
self,
94100
own_address=0,
95101
own_channel=0,
96102
encryption_key=0x2333,
97-
air_data_rate=Def.BW125K_SF9,
98-
subpacket_size=Def.SUBPACKET_200_BYTE,
99-
rssi_ambient_noise_flag=Def.RSSI_AMBIENT_NOISE_ENABLE,
100-
transmitting_power=Def.TX_POWER_13dBm,
101-
rssi_byte_flag=Def.RSSI_BYTE_ENABLE,
102-
transmission_method_type=Def.UART_P2P_MODE,
103-
lbt_flag=Def.LBT_DISABLE,
104-
wor_cycle=Def.WOR_2000MS,
105-
):
103+
air_data_rate=0b0000_0010, # BW500K_SF5
104+
subpacket_size=0b0000_0000, # SUBPACKET_200_BYTE
105+
rssi_ambient_noise_flag=0b0000_0000, # RSSI_AMBIENT_NOISE_DISABLE
106+
transmitting_power=0b0000_0000, # TX_POWER_13dBm
107+
rssi_byte_flag=0b0000_0000, # RSSI_BYTE_DISABLE
108+
transmission_method_type=0b0000_0000, # UART_TT_MODE
109+
lbt_flag=0b0000_0000, # LBT_DISABLE
110+
wor_cycle=0b0000_0011, # WOR_2000MS
111+
) -> bool:
106112
if not self._conf_range(own_channel, 0, 30):
107113
return False
108114

109-
self.subpacket_size = subpacket_size
110-
self.max_len = 0
111-
if self.subpacket_size == Def.SUBPACKET_128_BYTE:
115+
if subpacket_size == self.SUBPACKET_128_BYTE:
112116
self.max_len = 128
113-
elif self.subpacket_size == Def.SUBPACKET_64_BYTE:
117+
elif subpacket_size == self.SUBPACKET_64_BYTE:
114118
self.max_len = 64
115-
elif self.subpacket_size == Def.SUBPACKET_32_BYTE:
119+
elif subpacket_size == self.SUBPACKET_32_BYTE:
116120
self.max_len = 32
117121
else:
118122
self.max_len = 200
119123

120-
command = [0xC0, 0x00, 0x08]
121-
ADDH = own_address >> 8
122-
ADDL = own_address & 0xFF
123-
command.extend([ADDH, ADDL])
124+
# Configuration
125+
struct.pack_into(">B", self._TXD_BUFFER, 0, 0xC0)
126+
struct.pack_into(">B", self._TXD_BUFFER, 1, 0x00)
127+
struct.pack_into(">B", self._TXD_BUFFER, 2, 0x08)
124128

125-
REG0 = (Def.BAUD_9600 << 5) | air_data_rate
126-
command.append(REG0)
129+
# Register Address 00H, 01H
130+
struct.pack_into(">H", self._TXD_BUFFER, 3, own_address)
127131

128-
REG1 = (subpacket_size << 6) | (rssi_ambient_noise_flag << 5) | transmitting_power
129-
command.append(REG1)
132+
# Register Address 02H
133+
REG0 = self.BAUD_9600 | air_data_rate
134+
struct.pack_into(">B", self._TXD_BUFFER, 5, REG0)
130135

131-
command.append(own_channel)
136+
# Register Address 03H
137+
REG1 = subpacket_size | rssi_ambient_noise_flag | transmitting_power
138+
struct.pack_into(">B", self._TXD_BUFFER, 6, REG1)
132139

133-
REG3 = (
134-
(rssi_byte_flag << 7) | (transmission_method_type << 6) | (lbt_flag << 4) | wor_cycle
135-
)
136-
command.append(REG3)
140+
# Register Address 04H
141+
struct.pack_into(">B", self._TXD_BUFFER, 7, own_channel)
137142

138-
CRYPT_H = encryption_key >> 8
139-
CRYPT_L = encryption_key & 0xFF
140-
command.extend([CRYPT_H, CRYPT_L])
143+
# Register Address 05H
144+
self.rssi_byte_flag = rssi_byte_flag
145+
REG3 = self.rssi_byte_flag | transmission_method_type | wor_cycle
146+
struct.pack_into(">B", self._TXD_BUFFER, 8, REG3)
141147

142-
self.uart.write(bytes(command))
148+
# Register Address 06H, 07H
149+
struct.pack_into(">H", self._TXD_BUFFER, 9, encryption_key)
143150

151+
command = memoryview(self._TXD_BUFFER[0:11])
152+
self.uart.write(command)
144153
time.sleep_ms(100) # wait for response
145154

146155
response = []
@@ -154,68 +163,73 @@ def setup(
154163
return False
155164
return True
156165

157-
def _recvCallback(self):
166+
def _recv_task(self) -> None:
158167
response = bytes()
159168
rssi = 0
160169
_ = self.uart.read()
161170
while self.recv_running:
162-
if self.uart.any():
163-
response += self.uart.read()
164-
elif len(response) > 0:
165-
time.sleep_ms(10)
166-
if not self.uart.any():
167-
rssi = int(response[-1]) - 256
168-
self.receive_callback(response[:-1], rssi)
169-
response = bytes()
171+
response, rssi = self.receive()
172+
if len(response):
173+
self.receive_callback(response, rssi)
170174
time.sleep_ms(10)
171175

172-
def receiveNoneBlock(self, receive_callback):
176+
def receive_none_block(self, receive_callback: function) -> None:
173177
if not self.recv_running:
174178
self.recv_running = True
175179
self.receive_callback = receive_callback
176-
_thread.start_new_thread(self._recvCallback, ())
180+
# FIXME: Threads cannot be automatically destroyed when the
181+
# application is interrupted.
182+
_thread.start_new_thread(self._recv_task, ())
183+
184+
def receiveNoneBlock(self, receive_callback: function) -> None:
185+
return self.receive_none_block(receive_callback)
177186

178-
def stopReceive(self):
187+
def stop_receive(self) -> None:
179188
self.recv_running = False
180189
time.sleep_ms(50)
181190
self.receive_callback = None
182191

183-
def receive(self, timeout=1000):
192+
def stopReceive(self) -> None:
193+
return self.stop_receive()
194+
195+
def receive(self, timeout=1000) -> tuple[bytes, int]:
184196
start = time.ticks_ms()
197+
read_length = 0
185198
response = bytes()
186-
rssi = 0
199+
rssi = 1
187200
while True:
188201
if time.ticks_ms() - start > timeout:
189202
break
190203

191204
if self.uart.any():
192-
response += self.uart.read()
193-
194-
elif len(response) > 0:
205+
read_length += self.uart.readinto(self._RXD_BUFFER)
206+
elif read_length > 0:
195207
time.sleep_ms(10)
196208
if not self.uart.any():
197-
rssi = int(response[-1]) - 256
209+
RXD_BUFFER = memoryview(self._RXD_BUFFER[0:read_length])
210+
if self.rssi_byte_flag == self.RSSI_BYTE_ENABLE:
211+
response, rssi = struct.unpack_from(
212+
"<%dsB" % (read_length - 1), RXD_BUFFER
213+
)
214+
rssi = rssi - 256
215+
else:
216+
response = struct.unpack_from("<%ds" % read_length, RXD_BUFFER)
198217
break
199218
time.sleep_ms(10)
200-
return response[:-1], rssi
201-
202-
def send(self, target_address, target_channel, send_data):
203-
if type(send_data) is str:
204-
send_data = send_data.encode("utf-8")
205-
206-
if type(send_data) is list:
207-
send_data = bytearray(send_data)
219+
return response, rssi
208220

221+
def send(self, target_address: int, target_channel: int, send_data: bytes | str) -> bool:
209222
if len(send_data) > self.max_len: # Adjust based on allowed packet size
210223
print("ERROR: Length of send_data over %d bytes." % self.max_len)
211224
return False
212225

213-
target_address_H = target_address >> 8
214-
target_address_L = target_address & 0xFF
215-
216-
frame = bytearray([target_address_H, target_address_L, target_channel])
217-
frame.extend(send_data)
218-
219-
self.uart.write(frame)
226+
FRAME = memoryview(self._TXD_BUFFER[0 : 3 + len(send_data)])
227+
struct.pack_into(">HB", FRAME, 0, target_address, target_channel)
228+
if type(send_data) is str:
229+
struct.pack_into("%ds" % len(send_data), FRAME, 3, send_data)
230+
else:
231+
for i in range(len(send_data)):
232+
FRAME[3 + i] = send_data[i]
233+
self.uart.write(FRAME)
220234

221235
return True

0 commit comments

Comments
 (0)