Skip to content

Commit 29e7bfc

Browse files
author
noname
committed
UART test
1 parent 42637f7 commit 29e7bfc

12 files changed

+1194
-30
lines changed

.idea/vcs.xml

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto_msg.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from _socket import inet_ntoa
2+
3+
from proto.proto_py import uart_pb2
4+
from enum import Enum
5+
6+
7+
RX_BUFFER = bytearray()
8+
TX_COMPLETE = True
9+
TX_SPACE = 64
10+
SEQ_NUM = 0
11+
12+
13+
class UartId(Enum):
14+
UART1 = 0
15+
UART2 = 1
16+
17+
18+
def encode_uart_config_msg(uart_id: UartId, baud_rate: int) -> bytes:
19+
global SEQ_NUM
20+
SEQ_NUM += 1
21+
msg = uart_pb2.UartMsg()
22+
23+
if uart_id == UartId.UART1:
24+
msg.cfg_msg.id = uart_pb2.UartId.UART1
25+
else:
26+
msg.cfg_msg.id = uart_pb2.UartId.UART2
27+
28+
msg.cfg_msg.baudrate = baud_rate
29+
msg.sequence_number = SEQ_NUM
30+
31+
return msg.SerializeToString()
32+
33+
34+
def encode_uart_data_msg(uart_id: UartId, data: bytes) -> bytes:
35+
global SEQ_NUM
36+
SEQ_NUM += 1
37+
msg = uart_pb2.UartMsg()
38+
39+
if uart_id == UartId.UART1:
40+
msg.data_msg.id = uart_pb2.UartId.UART1
41+
else:
42+
msg.data_msg.id = uart_pb2.UartId.UART2
43+
44+
msg.data_msg.data = data
45+
msg.sequence_number = SEQ_NUM
46+
47+
return msg.SerializeToString()
48+
49+
50+
def decode_uart_msg(data: bytes):
51+
global SEQ_NUM
52+
msg = uart_pb2.UartMsg()
53+
msg.ParseFromString(data)
54+
55+
inner_msg = msg.WhichOneof("msg")
56+
# print("Inner msg:", inner_msg)
57+
if inner_msg == "data_msg":
58+
global RX_BUFFER
59+
RX_BUFFER += msg.data_msg.data
60+
elif inner_msg == "status_msg":
61+
global TX_COMPLETE, TX_SPACE
62+
if msg.sequence_number == SEQ_NUM:
63+
TX_COMPLETE = msg.status_msg.tx_complete
64+
TX_SPACE = msg.status_msg.tx_space
65+
print("Status: tx_complete {}, tx_space {}, tx_overflow {}, seq_num {}"
66+
.format(msg.status_msg.tx_complete, msg.status_msg.tx_space,
67+
msg.status_msg.tx_overflow, msg.sequence_number))
68+
if msg.status_msg.tx_overflow:
69+
raise Exception("Tx overflow!")
70+
else:
71+
print("Rejected status msg! --------------------------------------->")

serial_example.py

+47-29
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,71 @@
33
"""A simple python script template.
44
"""
55

6-
import serial
7-
import tf.TinyFrame as TF
86
import sys
7+
import enum
98
import time
9+
import string
10+
import random
11+
import serial
12+
import tiny_frame
13+
import proto_msg as pm
1014

11-
TYPE_DEFAULT = 0x00
12-
TYPE_UART = 0x01
13-
TYPE_PERIPHERAL = 0x02
14-
TYPE_CENTRAL = 0x03
15+
TX_LOOPS = 100000
16+
MIN_TX_SIZE = 1
17+
MAX_DATA_SIZE = 64
18+
TX_HISTORY = bytearray()
19+
TX_COUNTER = 0
1520

1621

17-
def fallback_listener(tf, msg):
18-
print("Fallback listener")
19-
print(msg.data)
22+
def uart_send(tf):
23+
global TX_COUNTER, TX_HISTORY
24+
if pm.TX_SPACE < MIN_TX_SIZE:
25+
return
2026

27+
tx_data = "This is a test. With little data ({}).".format(TX_COUNTER)
28+
size = random.randint(MIN_TX_SIZE, min(MAX_DATA_SIZE, pm.TX_SPACE))
29+
tx_data = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(size))
2130

22-
def uart_listener(tf, msg):
23-
print("Uart listener")
24-
print(msg.data)
31+
if pm.TX_SPACE >= len(tx_data) and TX_COUNTER < TX_LOOPS:
32+
print("Data: '{}'".format(tx_data))
33+
tx_data = bytes(tx_data, 'ascii')
34+
msg = pm.encode_uart_data_msg(pm.UartId.UART1, tx_data)
35+
print("Send msg (id={}, len={}, tx={}, seq={}) : {}".format(TX_COUNTER, len(msg), len(tx_data), pm.SEQ_NUM, msg))
36+
37+
tf.send(tiny_frame.TfMsgType.TYPE_UART.value, msg, 0)
38+
pm.TX_SPACE -= len(tx_data)
39+
TX_COUNTER += 1
40+
TX_HISTORY += tx_data
2541

2642

2743
def main(arguments):
44+
global TX_HISTORY
2845
print("TinyFrame test sender")
2946

3047
with serial.Serial('COM4', 115200, timeout=1) as ser:
31-
tf = TF.TinyFrame()
32-
tf.SOF_BYTE = 0x01
33-
tf.ID_BYTES = 1
34-
tf.LEN_BYTES = 1
35-
tf.TYPE_BYTES = 1
36-
tf.CKSUM_TYPE = 'xor'
37-
tf.write = ser.write
38-
39-
# Add listeners
40-
tf.add_fallback_listener(fallback_listener)
41-
tf.add_type_listener(TYPE_UART, uart_listener)
42-
43-
# Send a frame
44-
tf.send(TYPE_UART, b"This are more than 64 bytes. This verifies that the frame is only processed when its complete.", 0)
45-
time.sleep(1)
48+
tf = tiny_frame.tf_init(ser.write)
4649

4750
while True:
51+
uart_send(tf)
4852
if ser.in_waiting > 0:
4953
# Read the incoming data
50-
data = ser.read(ser.in_waiting)
54+
rx_data = ser.read(ser.in_waiting)
5155
# print(data)
52-
tf.accept(data)
56+
tf.accept(rx_data)
57+
58+
rx_len = len(pm.RX_BUFFER)
59+
if rx_len > 0:
60+
if pm.RX_BUFFER[:rx_len] == TX_HISTORY[:rx_len]:
61+
print("Loop ok for {} bytes: '{}'".format(rx_len, pm.RX_BUFFER.decode("ascii")))
62+
TX_HISTORY = TX_HISTORY[rx_len:]
63+
pm.RX_BUFFER.clear()
64+
if len(TX_HISTORY) == 0 and TX_COUNTER >= TX_LOOPS:
65+
break
66+
else:
67+
print("Data missmatch detected!")
68+
print(TX_HISTORY[:rx_len])
69+
print(pm.RX_BUFFER)
70+
raise Exception("Data missmatch!")
5371

5472

5573
if __name__ == '__main__':

tf/.gitignore

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
env/
12+
build/
13+
develop-eggs/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
28+
# PyInstaller
29+
# Usually these files are written by a python script from a template
30+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
31+
*.manifest
32+
*.spec
33+
34+
# Installer logs
35+
pip-log.txt
36+
pip-delete-this-directory.txt
37+
38+
# Unit test / coverage reports
39+
htmlcov/
40+
.tox/
41+
.coverage
42+
.coverage.*
43+
.cache
44+
nosetests.xml
45+
coverage.xml
46+
*.cover
47+
.hypothesis/
48+
49+
# Translations
50+
*.mo
51+
*.pot
52+
53+
# Django stuff:
54+
*.log
55+
local_settings.py
56+
57+
# Flask stuff:
58+
instance/
59+
.webassets-cache
60+
61+
# Scrapy stuff:
62+
.scrapy
63+
64+
# Sphinx documentation
65+
docs/_build/
66+
67+
# PyBuilder
68+
target/
69+
70+
# Jupyter Notebook
71+
.ipynb_checkpoints
72+
73+
# pyenv
74+
.python-version
75+
76+
# celery beat schedule file
77+
celerybeat-schedule
78+
79+
# SageMath parsed files
80+
*.sage.py
81+
82+
# dotenv
83+
.env
84+
85+
# virtualenv
86+
.venv
87+
venv/
88+
ENV/
89+
90+
# Spyder project settings
91+
.spyderproject
92+
.spyproject
93+
94+
# Rope project settings
95+
.ropeproject
96+
97+
# mkdocs documentation
98+
/site
99+
100+
# mypy
101+
.mypy_cache/

0 commit comments

Comments
 (0)