Skip to content
Snippets Groups Projects
Commit c1f1e2cb authored by Václav Jelínek's avatar Václav Jelínek
Browse files

Add i2c master slave menu programs

parent 18e2c15a
No related branches found
No related tags found
1 merge request!12Major update of menu visuals and example programs
Pipeline #107009 canceled
......@@ -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)
......
......@@ -5,7 +5,7 @@ robot = Robot()
display_show_startup(robot)
import utime
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(utime.tick_diff(utime.ticks_ms(),robot.start_time)/1000)}\n")
f.write(f"ERROR program: {program_name}, time since reset: {int(time.ticks_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)
utime.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")
utime.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 = utime.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: ", utime.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
utime.sleep(0.05)
time.sleep(0.05)
if __name__ == '__main__':
......
......@@ -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
......
......@@ -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 = 0x50
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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment