Skip to content

Commit 333da66

Browse files
authored
Merge pull request #3 from sparkfun/micropython-rp2040
add micropython RP2040 i2c driver
2 parents f895b05 + 2d03d85 commit 333da66

File tree

2 files changed

+154
-4
lines changed

2 files changed

+154
-4
lines changed

qwiic_i2c/__init__.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,26 @@
6363
#
6464
#-----------------------------------------------------------------------------
6565
# Drivers and driver baseclass
66-
from .i2c_driver import I2CDriver
67-
from .linux_i2c import LinuxI2C
68-
from .circuitpy_i2c import CircuitPythonI2C
66+
from .i2c_driver import I2CDriver
6967

70-
_drivers = [LinuxI2C, CircuitPythonI2C]
68+
# All supported platform module and class names
69+
_supported_platforms = {
70+
"linux_i2c": "LinuxI2C",
71+
"circuitpy_i2c": "CircuitPythonI2C",
72+
"micropython_i2c": "MicroPythonI2C"
73+
}
74+
75+
# List of platform drivers found on this system
76+
_drivers = []
77+
78+
# Loop through all supported platform drivers, see if they're included, and
79+
# append them to the driver list if so
80+
for module_name, class_name in _supported_platforms.items():
81+
try:
82+
sub_module = __import__("qwiic_i2c." + module_name, None, None, [None])
83+
_drivers.append(getattr(sub_module, class_name))
84+
except:
85+
pass
7186

7287
_theDriver = None
7388

qwiic_i2c/micropython_i2c.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#-----------------------------------------------------------------------------
2+
# micropython_i2c.py
3+
#
4+
# Encapsulate MicroPython port I2C interface
5+
#------------------------------------------------------------------------
6+
#
7+
# Written by oclyke, Feb 2021
8+
#
9+
#
10+
# More information on qwiic is at https://www.sparkfun.com/qwiic
11+
#
12+
# Do you like this library? Help support SparkFun. Buy a board!
13+
#
14+
#==================================================================================
15+
# Copyright (c) 2021 SparkFun Electronics
16+
#
17+
# Permission is hereby granted, free of charge, to any person obtaining a copy
18+
# of this software and associated documentation files (the "Software"), to deal
19+
# in the Software without restriction, including without limitation the rights
20+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21+
# copies of the Software, and to permit persons to whom the Software is
22+
# furnished to do so, subject to the following conditions:
23+
#
24+
# The above copyright notice and this permission notice shall be included in all
25+
# copies or substantial portions of the Software.
26+
#
27+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33+
# SOFTWARE.
34+
#==================================================================================
35+
36+
from .i2c_driver import I2CDriver
37+
38+
import sys
39+
40+
_PLATFORM_NAME = "MicroPython"
41+
42+
# used internally in this file to get i2c class object
43+
def _connectToI2CBus(freq=400000):
44+
try:
45+
from machine import I2C, Pin
46+
# Todo: Don't hard code I2C pin and port!
47+
return I2C(id=1, scl=Pin(19), sda=Pin(18), freq=freq)
48+
except Exception as e:
49+
print(str(e))
50+
print('error: failed to connect to i2c bus')
51+
return None
52+
53+
class MicroPythonI2C(I2CDriver):
54+
55+
# Constructor
56+
name = _PLATFORM_NAME
57+
_i2cbus = None
58+
59+
def __init__(self):
60+
I2CDriver.__init__(self) # init super
61+
62+
@classmethod
63+
def isPlatform(cls):
64+
try:
65+
return sys.implementation.name == 'micropython'
66+
except:
67+
return False
68+
69+
70+
#-------------------------------------------------------------------------
71+
# General get attribute method
72+
#
73+
# Used to intercept getting the I2C bus object - so we can perform a lazy
74+
# connect ....
75+
#
76+
def __getattr__(self, name):
77+
78+
if(name == "i2cbus"):
79+
if( self._i2cbus == None):
80+
self._i2cbus = _connectToI2CBus()
81+
return self._i2cbus
82+
83+
else:
84+
# Note - we call __getattribute__ to the super class (object).
85+
return super(I2CDriver, self).__getattribute__(name)
86+
87+
#-------------------------------------------------------------------------
88+
# General set attribute method
89+
#
90+
# Basically implemented to make the i2cbus attribute readonly to users
91+
# of this class.
92+
#
93+
def __setattr__(self, name, value):
94+
95+
if(name != 'i2cbus'):
96+
super(I2CDriver, self).__setattr__(name, value)
97+
98+
# read commands ----------------------------------------------------------
99+
def readWord(self, address, commandCode):
100+
buffer = self.i2cbus.readfrom_mem(address, commandCode, 2)
101+
return (buffer[1] << 8 ) | buffer[0]
102+
103+
def readByte(self, address, commandCode):
104+
return self.i2cbus.readfrom_mem(address, commandCode, 1)[0]
105+
106+
def readBlock(self, address, commandCode, nBytes):
107+
return self.i2cbus.readfrom_mem(address, commandCode, nBytes)
108+
109+
110+
# write commands----------------------------------------------------------
111+
def writeCommand(self, address, commandCode):
112+
self.i2cbus.writeto(address, commandCode.to_bytes(1, 'little'))
113+
114+
def writeWord(self, address, commandCode, value):
115+
self.i2cbus.writeto_mem(address, commandCode, value.to_bytes(2, 'little'))
116+
117+
def writeByte(self, address, commandCode, value):
118+
self.i2cbus.writeto_mem(address, commandCode, value.to_bytes(1, 'little'))
119+
120+
def writeBlock(self, address, commandCode, value):
121+
self.i2cbus.writeto_mem(address, commandCode, bytes(value))
122+
123+
124+
# scan -------------------------------------------------------------------
125+
@classmethod
126+
def scan(cls):
127+
""" Returns a list of addresses for the devices connected to the I2C bus."""
128+
129+
if cls._i2cbus == None:
130+
cls._i2cbus = _connectToI2CBus()
131+
132+
if cls._i2cbus == None:
133+
return []
134+
135+
return cls._i2cbus.scan()

0 commit comments

Comments
 (0)