Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
O
Open-Cube FW
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Open Cube
Open-Cube FW
Commits
c1f1e2cb
Commit
c1f1e2cb
authored
5 months ago
by
Václav Jelínek
Browse files
Options
Downloads
Patches
Plain Diff
Add i2c master slave menu programs
parent
18e2c15a
No related branches found
Branches containing commit
No related tags found
1 merge request
!12
Major update of menu visuals and example programs
Pipeline
#107009
canceled
5 months ago
Stage: build
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
lib/robot.py
+1
-1
1 addition, 1 deletion
lib/robot.py
main/main.py
+10
-8
10 additions, 8 deletions
main/main.py
menu_programs/i2c_master.py
+6
-3
6 additions, 3 deletions
menu_programs/i2c_master.py
menu_programs/i2c_slave.py
+87
-86
87 additions, 86 deletions
menu_programs/i2c_slave.py
with
104 additions
and
98 deletions
lib/robot.py
+
1
−
1
View file @
c1f1e2cb
...
...
@@ -19,7 +19,7 @@ MOTOR_NUM = len(MOTOR_PORT_PINS)
# Object is initialized in the main program (main.py) after the startup of the cube and can be used in user programs
class
Robot
:
def
__init__
(
self
):
start_time
=
ticks_ms
()
self
.
start_time
=
ticks_ms
()
# Set pins 0, 1 to input to correctly initialize HW UART0
Pin
(
0
,
mode
=
Pin
.
IN
)
Pin
(
1
,
mode
=
Pin
.
IN
)
...
...
This diff is collapsed.
Click to expand it.
main/main.py
+
10
−
8
View file @
c1f1e2cb
...
...
@@ -5,7 +5,7 @@ robot = Robot()
display_show_startup
(
robot
)
import
u
time
import
time
import
os
import
sys
import
micropython
...
...
@@ -56,7 +56,7 @@ def main():
print
(
"
Previous log too long, file deleted
"
)
f
.
write
(
"
Previous log too long, file deleted
\n
"
)
f
.
write
(
"
--------------------------------------------------
\n
"
)
f
.
write
(
f
"
ERROR program:
{
program_name
}
, time since reset:
{
int
(
u
time
.
tick_diff
(
u
time
.
ticks_ms
(),
robot
.
start_time
)
/
1000
)
}
\n
"
)
f
.
write
(
f
"
ERROR program:
{
program_name
}
, time since reset:
{
int
(
time
.
tick
s
_diff
(
time
.
ticks_ms
(),
robot
.
start_time
)
)
}
ms
\n
"
)
sys
.
print_exception
(
e
,
f
)
f
.
write
(
"
--------------------------------------------------
\n
"
)
...
...
@@ -115,7 +115,7 @@ def main():
sys
.
print_exception
(
e
)
log_error
(
robot
,
e
,
program_name
)
display_show_error
(
robot
)
u
time
.
sleep
(
1.0
)
time
.
sleep
(
1.0
)
finally
:
# Deinit all sensors, motors and uart if initialized by user program
# after user program ends
...
...
@@ -124,7 +124,7 @@ def main():
gc
.
collect
()
robot
.
esp
.
esp_running
=
False
print
(
"
Program finished
\n
"
)
u
time
.
sleep_ms
(
200
)
# wait for all components of the Cube to start
time
.
sleep_ms
(
200
)
# wait for all components of the Cube to start
# Initialize variables
robot_state
=
0
...
...
@@ -171,13 +171,13 @@ def main():
# Connect to and reset ESP32 to BT mode if it is not running
if
not
robot
.
esp
.
running
()
and
counter
%
10
==
0
:
s
=
u
time
.
ticks_ms
()
s
=
time
.
ticks_ms
()
if
not
robot
.
esp
.
reset
(
100
):
esp_reset_failed_counter
+=
1
else
:
esp_reset_failed_counter
=
0
esp_reset_counter
=
counter
print
(
"
ESP32 reset time:
"
,
u
time
.
ticks_ms
()
-
s
)
print
(
"
ESP32 reset time:
"
,
time
.
ticks_ms
()
-
s
)
if
robot
.
esp
.
running
()
and
counter
-
esp_reset_counter
==
10
:
robot
.
esp
.
set_name_nonblocking
(
esp_default_name
,
100
)
print
(
"
ESP BT name:
"
,
esp_default_name
)
...
...
@@ -278,6 +278,7 @@ def main():
sensor_test_menu
=
Menu
.
SEN_TEST_PORT
menu_debounce
=
1
elif
sensor_test_menu
==
Menu
.
SEN_TEST_PORT
:
robot_state
=
1
program_name
=
menu_programs_functions
[
sensor_test_menu_stype
][
0
]
print
(
"
Running sensor test:
"
,
program_name
)
...
...
@@ -288,10 +289,11 @@ def main():
log_error
(
robot
,
e
,
program_name
)
display_show_error
(
robot
)
robot
.
deinit_all
()
sensor_test_menu
=
=
Menu
.
SEN_TEST_PROGRAM
sensor_test_menu
=
Menu
.
SEN_TEST_PROGRAM
sensor_test_menu_port
=
0
robot_state
=
0
menu_debounce
=
1
ok_pressed
=
0
continue
elif
current_menu
==
Menu
.
CUBE_TEST
:
...
...
@@ -333,7 +335,7 @@ def main():
display_fill_battery
(
robot
,
bat_voltage
)
robot
.
display
.
show
()
counter
+=
1
u
time
.
sleep
(
0.05
)
time
.
sleep
(
0.05
)
if
__name__
==
'
__main__
'
:
...
...
This diff is collapsed.
Click to expand it.
menu_programs/i2c_master.py
+
6
−
3
View file @
c1f1e2cb
...
...
@@ -10,12 +10,15 @@ def i2c_master_run(robot):
i2c
=
I2C
(
id
=
0
,
scl
=
Pin
(
17
),
sda
=
Pin
(
16
),
freq
=
100000
)
data_received
=
0x5F
data_sending
=
0
debounce
=
False
robot
.
display
.
fill
(
0
)
robot
.
display
.
centered_text
(
f
"
I2C master
"
,
0
,
1
)
robot
.
display
.
text
(
'
<
'
,
0
,
54
,
1
)
robot
.
display
.
show
()
utime
.
sleep
(
0.2
)
while
True
:
robot
.
display
.
fill
(
0
)
robot
.
display
.
centered_text
(
f
"
I2C slave
"
,
0
,
1
)
...
...
@@ -24,7 +27,7 @@ def i2c_master_run(robot):
robot
.
display
.
text
(
'
<
'
,
0
,
54
,
1
)
robot
.
display
.
show
()
i2c
.
writeto
(
0x41
,
data_sending
+
ASCII_a
)
i2c
.
writeto
(
0x41
,
(
data_sending
+
ASCII_a
)
.
to_bytes
(
1
,
'
big
'
))
data_received
=
int
.
from_bytes
(
i2c
.
readfrom
(
0x41
,
1
),
'
big
'
)
buttons
=
robot
.
buttons
.
pressed
()
...
...
@@ -32,11 +35,11 @@ def i2c_master_run(robot):
break
if
not
debounce
:
if
buttons
[
Button
.
UP
]:
data_sending
+
=
1
data_sending
-
=
1
data_sending
=
data_sending
%
26
debounce
=
True
if
buttons
[
Button
.
DOWN
]:
data_sending
-
=
1
data_sending
+
=
1
data_sending
=
data_sending
%
26
debounce
=
True
...
...
This diff is collapsed.
Click to expand it.
menu_programs/i2c_slave.py
+
87
−
86
View file @
c1f1e2cb
...
...
@@ -2,98 +2,99 @@ import utime
from
machine
import
mem32
,
mem8
,
Pin
from
lib.robot_consts
import
Button
ASCII_a
=
97
def
i2c_slave_run
(
robot
):
ASCII_a
=
97
class
i2c_slave
():
I2C0_BASE
=
0x40044000
I2C1_BASE
=
0x40048000
IO_BANK0_BASE
=
0x40014000
mem_rw
=
0x0000
mem_xor
=
0x1000
mem_set
=
0x2000
mem_clr
=
0x3000
IC_CON
=
0
IC_TAR
=
4
IC_SAR
=
8
IC_DATA_CMD
=
0x10
IC_RAW_INTR_STAT
=
0x34
IC_RX_TL
=
0x38
IC_TX_TL
=
0x3C
IC_CLR_INTR
=
0x40
IC_CLR_RD_REQ
=
0x50
IC_CLR_TX_ABRT
=
0x54
IC_ENABLE
=
0x6c
IC_STATUS
=
0x70
def
write_reg
(
self
,
reg
,
data
,
method
=
0
):
mem32
[
self
.
i2c_base
|
method
|
reg
]
=
data
class
i2c_slave
():
I2C0_BASE
=
0x40044000
I2C1_BASE
=
0x40048000
IO_BANK0_BASE
=
0x40014000
def
set_reg
(
self
,
reg
,
data
):
self
.
write_reg
(
reg
,
data
,
method
=
self
.
mem_set
)
mem_rw
=
0x0000
mem_xor
=
0x1000
mem_set
=
0x2000
mem_clr
=
0x3000
def
clr_reg
(
self
,
reg
,
data
):
self
.
write_reg
(
reg
,
data
,
method
=
self
.
mem_clr
)
def
__init__
(
self
,
i2cID
=
0
,
sda
=
16
,
scl
=
17
,
slaveAddress
=
0x41
):
self
.
scl
=
scl
self
.
sda
=
sda
self
.
slaveAddress
=
slaveAddress
self
.
i2c_ID
=
i2cID
if
self
.
i2c_ID
=
=
0
:
self
.
i2c_base
=
self
.
I2C0_BASE
else
:
self
.
i2c_base
=
self
.
I2C1_BASE
IC_CON
=
0
IC_TAR
=
4
IC_SAR
=
8
IC_DATA_CMD
=
0x10
IC_RAW_INTR_STAT
=
0x34
IC_RX_TL
=
0x38
IC_TX_TL
=
0x3C
IC_CLR_INTR
=
0x40
IC_CLR_RD_REQ
=
0
x50
IC_CLR_TX_ABRT
=
0x54
IC_ENABLE
=
0x6c
IC_STATUS
=
0x70
# 1 Disable DW_apb_i2c
self
.
clr_reg
(
self
.
IC_ENABLE
,
1
)
# 2 set slave address
# clr bit 0 to 9
# set slave address
self
.
clr_reg
(
self
.
IC_SAR
,
0x1ff
)
self
.
set_reg
(
self
.
IC_SAR
,
self
.
slaveAddress
&
0x1ff
)
# 3 write IC_CON 7 bit, enable in slave-only
self
.
clr_reg
(
self
.
IC_CON
,
0b01001001
)
# set SDA PIN
mem32
[
self
.
IO_BANK0_BASE
|
self
.
mem_clr
|
(
4
+
8
*
self
.
sda
)
]
=
0x1f
mem32
[
self
.
IO_BANK0_BASE
|
self
.
mem_set
|
(
4
+
8
*
self
.
sda
)
]
=
3
# set SLA PIN
mem32
[
self
.
IO_BANK0_BASE
|
self
.
mem_clr
|
(
4
+
8
*
self
.
scl
)
]
=
0x1f
mem32
[
self
.
IO_BANK0_BASE
|
self
.
mem_set
|
(
4
+
8
*
self
.
scl
)
]
=
3
# 4 enable i2c
self
.
set_reg
(
self
.
IC_ENABLE
,
1
)
def
write_reg
(
self
,
reg
,
data
,
method
=
0
):
mem32
[
self
.
i2c_base
|
method
|
reg
]
=
data
def
set_reg
(
self
,
reg
,
data
):
self
.
write_reg
(
reg
,
data
,
method
=
self
.
mem_set
)
def
clr_reg
(
self
,
reg
,
data
):
self
.
write_reg
(
reg
,
data
,
method
=
self
.
mem_clr
)
def
__init__
(
self
,
i2cID
=
0
,
sda
=
16
,
scl
=
17
,
slaveAddress
=
0x41
):
self
.
scl
=
scl
self
.
sda
=
sda
self
.
slaveAddress
=
slaveAddress
self
.
i2c_ID
=
i2cID
if
self
.
i2c_ID
==
0
:
self
.
i2c_base
=
self
.
I2C0_BASE
else
:
self
.
i2c_base
=
self
.
I2C1_BASE
# 1 Disable DW_apb_i2c
self
.
clr_reg
(
self
.
IC_ENABLE
,
1
)
# 2 set slave address
# clr bit 0 to 9
# set slave address
self
.
clr_reg
(
self
.
IC_SAR
,
0x1ff
)
self
.
set_reg
(
self
.
IC_SAR
,
self
.
slaveAddress
&
0x1ff
)
# 3 write IC_CON 7 bit, enable in slave-only
self
.
clr_reg
(
self
.
IC_CON
,
0b01001001
)
# set SDA PIN
mem32
[
self
.
IO_BANK0_BASE
|
self
.
mem_clr
|
(
4
+
8
*
self
.
sda
)
]
=
0x1f
mem32
[
self
.
IO_BANK0_BASE
|
self
.
mem_set
|
(
4
+
8
*
self
.
sda
)
]
=
3
# set SLA PIN
mem32
[
self
.
IO_BANK0_BASE
|
self
.
mem_clr
|
(
4
+
8
*
self
.
scl
)
]
=
0x1f
mem32
[
self
.
IO_BANK0_BASE
|
self
.
mem_set
|
(
4
+
8
*
self
.
scl
)
]
=
3
# 4 enable i2c
self
.
set_reg
(
self
.
IC_ENABLE
,
1
)
def
anyRead
(
self
):
status
=
mem32
[
self
.
i2c_base
|
self
.
IC_RAW_INTR_STAT
]
&
0x20
if
status
:
return
True
return
False
def
anyRead
(
self
):
status
=
mem32
[
self
.
i2c_base
|
self
.
IC_RAW_INTR_STAT
]
&
0x20
if
status
:
return
True
return
False
def
put
(
self
,
data
):
# reset flag
self
.
clr_reg
(
self
.
IC_CLR_TX_ABRT
,
1
)
status
=
mem32
[
self
.
i2c_base
|
self
.
IC_CLR_RD_REQ
]
mem32
[
self
.
i2c_base
|
self
.
IC_DATA_CMD
]
=
data
&
0xff
def
put
(
self
,
data
):
# reset flag
self
.
clr_reg
(
self
.
IC_CLR_TX_ABRT
,
1
)
status
=
mem32
[
self
.
i2c_base
|
self
.
IC_CLR_RD_REQ
]
mem32
[
self
.
i2c_base
|
self
.
IC_DATA_CMD
]
=
data
&
0xff
def
any
(
self
):
# get IC_STATUS
status
=
mem32
[
self
.
i2c_base
|
self
.
IC_STATUS
]
# check RFNE receive fifio not empty
if
(
status
&
8
)
:
return
True
return
False
def
any
(
self
):
# get IC_STATUS
status
=
mem32
[
self
.
i2c_base
|
self
.
IC_STATUS
]
# check RFNE receive fifio not empty
if
(
status
&
8
)
:
return
True
return
False
def
get
(
self
):
while
not
self
.
any
():
pass
return
mem32
[
self
.
i2c_base
|
self
.
IC_DATA_CMD
]
&
0xff
def
get
(
self
):
while
not
self
.
any
():
pass
return
mem32
[
self
.
i2c_base
|
self
.
IC_DATA_CMD
]
&
0xff
def
i2c_slave_run
(
robot
):
i2c_slave
=
i2c_slave
()
i2c_slave_o
=
i2c_slave
()
data_received
=
0x5F
data_sending
=
0
debounce
=
False
robot
.
display
.
fill
(
0
)
robot
.
display
.
centered_text
(
f
"
I2C slave
"
,
0
,
1
)
...
...
@@ -106,20 +107,20 @@ def i2c_slave_run(robot):
robot
.
display
.
text
(
f
"
Received:
{
chr
(
data_received
)
}
"
,
0
,
24
,
1
)
robot
.
display
.
text
(
'
<
'
,
0
,
54
,
1
)
robot
.
display
.
show
()
if
i2c_slave
.
anyRead
():
data_received
=
i2c_slave
.
get
()
i2c_slave
.
put
(
data_sending
+
ASCII_a
)
if
i2c_slave
_o
.
anyRead
():
data_received
=
i2c_slave
_o
.
get
()
i2c_slave
_o
.
put
(
data_sending
+
ASCII_a
)
buttons
=
robot
.
buttons
.
pressed
()
if
buttons
[
Button
.
LEFT
]:
break
if
not
debounce
:
if
buttons
[
Button
.
UP
]:
data_sending
+
=
1
data_sending
-
=
1
data_sending
=
data_sending
%
26
debounce
=
True
if
buttons
[
Button
.
DOWN
]:
data_sending
-
=
1
data_sending
+
=
1
data_sending
=
data_sending
%
26
debounce
=
True
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment