├── PyMCP2221A ├── __init__.py ├── SMBus.py └── PyMCP2221A.py ├── example ├── PyMCP2221A │ ├── __init__.py │ ├── SMBus.py │ └── PyMCP2221A.py ├── HIDAPItest.py ├── MCP2221_DAC.py ├── MCP2221_ADC.py ├── MCP2221_ClockOUT.py ├── MCP2221_i2cdetect.py ├── MCP2221_GPIO.py └── MCP2221_EEPROM_WriteReadTest.py ├── pypi ├── main │ ├── PyMCP2221A │ │ ├── __init__.py │ │ ├── SMBus.py │ │ └── PyMCP2221A.py │ ├── setup.cfg │ ├── setup.py │ ├── LICENSE │ └── README.rst └── armv7l │ ├── PyMCP2221A │ ├── __init__.py │ ├── hid.so │ ├── hidraw.so │ ├── SMBus.py │ └── PyMCP2221A.py │ ├── setup.cfg │ ├── setup.py │ ├── LICENSE │ └── README.rst ├── img └── mcp2221.PNG ├── Makefile ├── memo.rst ├── LICENSE ├── .gitignore ├── README_JP.rst └── README.rst /PyMCP2221A/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/PyMCP2221A/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pypi/main/PyMCP2221A/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pypi/armv7l/PyMCP2221A/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/mcp2221.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonNoise/PyMCP2221A/HEAD/img/mcp2221.PNG -------------------------------------------------------------------------------- /pypi/main/setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | 4 | [egg_info] 5 | tag_svn_revision=false 6 | -------------------------------------------------------------------------------- /pypi/armv7l/setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | 4 | [egg_info] 5 | tag_svn_revision=false 6 | -------------------------------------------------------------------------------- /pypi/armv7l/PyMCP2221A/hid.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonNoise/PyMCP2221A/HEAD/pypi/armv7l/PyMCP2221A/hid.so -------------------------------------------------------------------------------- /pypi/armv7l/PyMCP2221A/hidraw.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nonNoise/PyMCP2221A/HEAD/pypi/armv7l/PyMCP2221A/hidraw.so -------------------------------------------------------------------------------- /example/HIDAPItest.py: -------------------------------------------------------------------------------- 1 | import hid 2 | # Check all usb device 3 | for d in hid.enumerate(0x04D8, 0x00DD): 4 | keys = d.keys() 5 | #keys.sort() 6 | for key in keys: 7 | print ("%s : %s" % (key, d[key])) 8 | 9 | print ("") 10 | 11 | print(hid.enumerate(0x04D8, 0x00DD)[0]["path"]) 12 | mcp2221a = hid.device() 13 | #mcp2221a.open(VID,PID) 14 | mcp2221a.open_path(hid.enumerate(0x04D8, 0x00DD)[0]["path"]) 15 | -------------------------------------------------------------------------------- /example/MCP2221_DAC.py: -------------------------------------------------------------------------------- 1 | from PyMCP2221A import PyMCP2221A 2 | 3 | import time 4 | gpio = PyMCP2221A.PyMCP2221A() 5 | 6 | gpio.Reset() 7 | time.sleep(1) 8 | mcp2221 = PyMCP2221A.PyMCP2221A() 9 | mcp2221.DAC_2_Init() 10 | print('-'*20) 11 | print('MCP2221(A) DAC Test') 12 | print('-'*20) 13 | print(" CTRL+C keys to exit.") 14 | 15 | while 1: 16 | for i in range(0,0x0F,1) : 17 | mcp2221.DAC_Datawrite(i) 18 | time.sleep(0.01) -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | init: 3 | mkdir -p build dist 4 | 5 | build-arm: 6 | cp LICENSE README.rst pypi/armv7l/ 7 | cp PyMCP2221A/* pypi/armv7l/PyMCP2221A 8 | cd pypi/armv7l && python3 setup.py bdist_wheel 9 | 10 | build-x86_64: 11 | cp LICENSE README.rst pypi/main/ 12 | cp PyMCP2221A/* pypi/main/PyMCP2221A 13 | cd pypi/main && python3 setup.py bdist_wheel 14 | 15 | clean: 16 | rm -r pypi/*/build/* 17 | rm -r pypi/*/dist/* 18 | rm -r pypi/*/*.egg-info 19 | -------------------------------------------------------------------------------- /example/MCP2221_ADC.py: -------------------------------------------------------------------------------- 1 | from PyMCP2221A import PyMCP2221A 2 | import time 3 | mcp2221 = PyMCP2221A.PyMCP2221A() 4 | 5 | mcp2221.Reset() 6 | time.sleep(1) 7 | mcp2221 = PyMCP2221A.PyMCP2221A() 8 | print('-'*20) 9 | print('MCP2221(A) ADC Test') 10 | print('-'*20) 11 | print(" CTRL+C keys to exit.") 12 | 13 | mcp2221.ADC_1_Init() 14 | mcp2221.ADC_2_Init() 15 | mcp2221.ADC_3_Init() 16 | while 1: 17 | mcp2221.ADC_DataRead() 18 | print("----------------") 19 | print ('AD1: 0x{:02x}'.format(mcp2221.ADC_1_data)) 20 | print ('AD2: 0x{:02x}'.format(mcp2221.ADC_2_data)) 21 | print ('AD3: 0x{:02x}'.format(mcp2221.ADC_3_data)) 22 | time.sleep(2) 23 | 24 | -------------------------------------------------------------------------------- /example/MCP2221_ClockOUT.py: -------------------------------------------------------------------------------- 1 | from PyMCP2221A import PyMCP2221A 2 | 3 | import time 4 | mcp2221 = PyMCP2221A.PyMCP2221A() 5 | #mcp2221.Reset() 6 | #time.sleep(1) 7 | 8 | mcp2221 = PyMCP2221A.PyMCP2221A() 9 | print('-'*20) 10 | print('MCP2221(A) ClockOut Test') 11 | print('-'*20) 12 | 13 | #========================================# 14 | # CLKDUTY_0 # duty 0% 15 | # CLKDUTY_25 # duty 25% 16 | # CLKDUTY_50 # duty 50% 17 | # CLKDUTY_75 # duty 75% 18 | # -------------------------------- # 19 | # CLKDIV_2 # 24MHz 20 | # CLKDIV_4 # 12MHz 21 | # CLKDIV_8 # 6MHz 22 | # CLKDIV_16 # 3MHz 23 | # CLKDIV_32 # 1.5MHz 24 | # CLKDIV_64 # 750KHz 25 | # CLKDIV_128 # 375KHz 26 | #========================================# 27 | mcp2221.ClockOut(mcp2221.CLKDUTY_50,mcp2221.CLKDIV_4) 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /pypi/main/setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # python setup.py register sdist upload 3 | from setuptools import setup 4 | 5 | import os 6 | f = open(os.path.join(os.path.dirname(__file__), 'README.rst')) 7 | long_description = f.read() 8 | f.close() 9 | 10 | setup( 11 | name = 'PyMCP2221A', 12 | version = '1.4.0', 13 | url="https://github.com/nonNoise/PyMCP2221A", 14 | keywords = ('Hardware,USB,HID,MCP2221,I2C,GPIO,I2C,SMBus'), 15 | description = 'This is a Microchip MCP2221(A) HID Library by python3.', 16 | license = 'MIT License', 17 | install_requires = ["hidapi"], 18 | long_description=long_description, 19 | packages=['PyMCP2221A'], 20 | author = ' Yuta Kitagami', 21 | author_email = 'kitagami@artifactnoise.com', 22 | platforms = ['Linux','Windows','Mac'], 23 | ) 24 | 25 | -------------------------------------------------------------------------------- /pypi/armv7l/setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # python setup.py register sdist upload 3 | from setuptools import setup 4 | 5 | import os 6 | f = open(os.path.join(os.path.dirname(__file__), 'README.rst')) 7 | long_description = f.read() 8 | f.close() 9 | 10 | setup( 11 | name = 'PyMCP2221A', 12 | version = '1.3.1', 13 | url="https://github.com/nonNoise/PyMCP2221A", 14 | keywords = ('Hardware,USB,HID,MCP2221,I2C,GPIO,I2C,SMBus'), 15 | description = 'This is a Microchip MCP2221(A) HID Library by python3.', 16 | license = 'MIT License', 17 | #install_requires = ["hidapi"], 18 | long_description=long_description, 19 | packages=['PyMCP2221A'], 20 | package_data={'PyMCP2221A': ['./hidraw.so','./hid.so']}, 21 | author = ' Yuta Kitagami', 22 | author_email = 'kitagami@artifactnoise.com', 23 | platforms = ['Linux','Windows','Mac'], 24 | ) 25 | 26 | -------------------------------------------------------------------------------- /example/MCP2221_i2cdetect.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | from PyMCP2221A import PyMCP2221A 6 | 7 | import time 8 | print('-'*50) 9 | print('MCP2221(A) i2cdetect ') 10 | print('-'*50) 11 | mcp2221 = PyMCP2221A.PyMCP2221A() 12 | mcp2221.Reset() 13 | mcp2221 = PyMCP2221A.PyMCP2221A() 14 | 15 | mcp2221.I2C_Init() 16 | 17 | print(" 0 1 2 3 4 5 6 7 8 9 A B C D E F ") 18 | for i in range(0x00,0x7F) : 19 | if(i%16==0 and i>0): 20 | print(" {:02X}".format(i-1)) 21 | 22 | if(mcp2221.I2C_Read(i,1) != -1): 23 | print(' {:02X}'.format(i), end='') 24 | else: 25 | print(' --', end='') 26 | #time.sleep(0.1) 27 | 28 | print("") 29 | 30 | 31 | -------------------------------------------------------------------------------- /example/MCP2221_GPIO.py: -------------------------------------------------------------------------------- 1 | from PyMCP2221A import PyMCP2221A 2 | 3 | import time 4 | gpio = PyMCP2221A.PyMCP2221A() 5 | gpio.Reset() 6 | time.sleep(1) 7 | 8 | print('-'*20) 9 | print('MCP2221(A) GPIO Test') 10 | print('-'*20) 11 | gpio = PyMCP2221A.PyMCP2221A() 12 | gpio.GPIO_Init() 13 | gpio.GPIO_0_OutputMode() 14 | gpio.GPIO_3_InputMode() 15 | print(" CTRL+C keys to exit.") 16 | while 1: 17 | if gpio.GPIO_3_Input()[0]: 18 | # Note that GPIO_3_Input() returns a tuple 19 | # GPIO_GetValue() is available if you don't need to know 20 | # what the Direction is 21 | print("GPIO 3 is HIGH!") 22 | gpio.GPIO_2_Output(1) 23 | time.sleep(0.1) 24 | gpio.GPIO_2_Output(0) 25 | time.sleep(0.1) 26 | gpio.GPIO_1_Output(1) 27 | time.sleep(0.1) 28 | gpio.GPIO_1_Output(0) 29 | time.sleep(0.1) 30 | gpio.GPIO_0_Output(1) 31 | time.sleep(0.1) 32 | gpio.GPIO_0_Output(0) 33 | time.sleep(0.1) 34 | 35 | 36 | -------------------------------------------------------------------------------- /memo.rst: -------------------------------------------------------------------------------- 1 | ====================================================================================== 2 | Memo. 3 | ====================================================================================== 4 | 5 | 6 | How to build hidlib ? 7 | --------------------------------------------------------------------------------------- 8 | 9 | Download cython-hidapi archive: 10 | 11 | $ git clone https://github.com/trezor/cython-hidapi.git 12 | 13 | $ cd cython-hidapi 14 | 15 | Initialize hidapi submodule: 16 | 17 | $ git submodule update --init 18 | 19 | Build cython-hidapi extension module: 20 | 21 | $ python setup.py build 22 | 23 | To use hidraw API instead of libusb add --without-libusb option: 24 | 25 | $ python setup.py build --without-libusb 26 | 27 | 28 | How did run at Raspberry Pi? 29 | --------------------------------------------------------------------------------------- 30 | 31 | git clone https://github.com/nonNoise/PyMCP2221A.git 32 | 33 | python 34 | 35 | from PyMCP2221A import PyMCP2221A 36 | 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Yuta KItagami 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pypi/armv7l/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Yuta KItagami 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /pypi/main/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Yuta KItagami 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /example/MCP2221_EEPROM_WriteReadTest.py: -------------------------------------------------------------------------------- 1 | from PyMCP2221A import PyMCP2221A 2 | 3 | import time 4 | mcp2221 = PyMCP2221A.PyMCP2221A() 5 | mcp2221.Reset() 6 | mcp2221 = PyMCP2221A.PyMCP2221A() 7 | print('-'*20) 8 | print('MCP2221(A) I2C Test') 9 | print('-'*20) 10 | print(" CTRL+C keys to exit.") 11 | 12 | mcp2221.I2C_Init() 13 | 14 | MAX = 0x00FF 15 | 16 | 17 | for i in range(MAX): 18 | data=[0]*3 19 | data[0] = (0xFF00&i)>>8 20 | data[1] = 0xFF&i 21 | data[2] = 0x00 22 | mcp2221.I2C_Write(0x50,data) 23 | print('-'*3 + " Clear " + '-'*3) 24 | time.sleep(1) 25 | for i in range(MAX): 26 | data=[0]*3 27 | data[0] = (0xFF00&i)>>8 28 | data[1] = 0xFF&i 29 | data[2] = 0xFF&i 30 | mcp2221.I2C_Write(0x50,data) 31 | print('-'*3 + " Write " + '-'*3) 32 | time.sleep(1) 33 | for i in range(MAX): 34 | data=[0]*2 35 | data[0] = (0xFF00&i)>>8 36 | data[1] = 0x00FF&i 37 | mcp2221.I2C_Write(0x50,data) 38 | rdata = mcp2221.I2C_Read(0x50,1) 39 | if(rdata == -1): 40 | print("Error") 41 | exit() 42 | #print ('0x{:02x}: 0x{:02x}'.format(i,rdata[0])) 43 | if(rdata[0]!=(0xFF&i)): 44 | pass 45 | print ('0x{:02x}: 0x{:02x}'.format(i,rdata[0])) 46 | #time.sleep(0.01) 47 | print('-'*3 + " Read " + '-'*3) 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 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/ 102 | -------------------------------------------------------------------------------- /pypi/armv7l/PyMCP2221A/SMBus.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | from PyMCP2221A import PyMCP2221A 6 | import time 7 | 8 | #-------------------------------------------------------------# 9 | # SMBus (system management bus) function compatible function # 10 | #-------------------------------------------------------------# 11 | class SMBus : 12 | def __init__(self,VID = 0x04D8,PID = 0x00DD,devnum = 0): 13 | self.mcp2221 = PyMCP2221A.PyMCP2221A(VID,PID,devnum) 14 | self.mcp2221.I2C_Init() 15 | def read_byte(self, addrs): 16 | return self.mcp2221.I2C_Read(addrs,1)[0] 17 | def write_byte(self, addrs,val): 18 | self.mcp2221.I2C_Write(addrs,1,[val]) 19 | def read_byte_data(self, addrs,cmd): 20 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 21 | return self.mcp2221.I2C_Read_Repeated(addrs,1)[0] 22 | def write_byte_data(self, addrs,cmd,val): 23 | self.mcp2221.I2C_Write(addrs,[cmd,val]) 24 | def read_word_data(self, addrs,cmd): 25 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 26 | tmp = self.mcp2221.I2C_Read_Repeated(addrs,2) 27 | return tmp[0] | tmp[1]<<8 28 | def write_word_data(self, addrs,cmd,val): 29 | self.mcp2221.I2C_Write(addrs,[cmd,val&0x00FF,(val&0xFF00)>>8]) 30 | def read_i2c_block_data(self, addrs,cmd,size): 31 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 32 | return self.mcp2221.I2C_Read_Repeated(addrs,size) 33 | def write_i2c_block_data(self, addrs,cmd,vals): 34 | self.mcp2221.I2C_Write(addrs,[cmd,vals]) 35 | 36 | -------------------------------------------------------------------------------- /example/PyMCP2221A/SMBus.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | from PyMCP2221A import PyMCP2221A 6 | import time 7 | 8 | #-------------------------------------------------------------# 9 | # SMBus (system management bus) function compatible function # 10 | #-------------------------------------------------------------# 11 | class SMBus : 12 | def __init__(self,VID = 0x04D8,PID = 0x00DD,devnum = 0): 13 | self.mcp2221 = PyMCP2221A.PyMCP2221A(VID,PID,devnum) 14 | self.mcp2221.I2C_Init() 15 | def read_byte(self, addrs): 16 | return self.mcp2221.I2C_Read(addrs,1)[0] 17 | def write_byte(self, addrs,val): 18 | self.mcp2221.I2C_Write(addrs,1,[val]) 19 | def read_byte_data(self, addrs,cmd): 20 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 21 | return self.mcp2221.I2C_Read_Repeated(addrs,1)[0] 22 | def write_byte_data(self, addrs,cmd,val): 23 | self.mcp2221.I2C_Write(addrs,[cmd,val]) 24 | def read_word_data(self, addrs,cmd): 25 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 26 | tmp = self.mcp2221.I2C_Read_Repeated(addrs,2) 27 | return tmp[0] | tmp[1]<<8 28 | def write_word_data(self, addrs,cmd,val): 29 | self.mcp2221.I2C_Write(addrs,[cmd,val&0x00FF,(val&0xFF00)>>8]) 30 | def read_i2c_block_data(self, addrs,cmd,size): 31 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 32 | return self.mcp2221.I2C_Read_Repeated(addrs,size) 33 | def write_i2c_block_data(self, addrs,cmd,vals): 34 | self.mcp2221.I2C_Write(addrs,[cmd,vals]) 35 | def reset(self): 36 | self.mcp2221.Reset() 37 | -------------------------------------------------------------------------------- /pypi/main/PyMCP2221A/SMBus.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | from PyMCP2221A import PyMCP2221A 6 | import time 7 | 8 | #-------------------------------------------------------------# 9 | # SMBus (system management bus) function compatible function # 10 | #-------------------------------------------------------------# 11 | class SMBus : 12 | def __init__(self,VID = 0x04D8,PID = 0x00DD,devnum = 0): 13 | self.mcp2221 = PyMCP2221A.PyMCP2221A(VID,PID,devnum) 14 | self.mcp2221.I2C_Init() 15 | def read_byte(self, addrs): 16 | return self.mcp2221.I2C_Read(addrs,1)[0] 17 | def write_byte(self, addrs,val): 18 | self.mcp2221.I2C_Write(addrs,1,[val]) 19 | def read_byte_data(self, addrs,cmd): 20 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 21 | return self.mcp2221.I2C_Read_Repeated(addrs,1)[0] 22 | def write_byte_data(self, addrs,cmd,val): 23 | self.mcp2221.I2C_Write(addrs,[cmd,val]) 24 | def read_word_data(self, addrs,cmd): 25 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 26 | tmp = self.mcp2221.I2C_Read_Repeated(addrs,2) 27 | return tmp[0] | tmp[1]<<8 28 | def write_word_data(self, addrs,cmd,val): 29 | self.mcp2221.I2C_Write(addrs,[cmd,val&0x00FF,(val&0xFF00)>>8]) 30 | def read_i2c_block_data(self, addrs,cmd,size): 31 | self.mcp2221.I2C_Write_No_Stop(addrs,[cmd]) 32 | return self.mcp2221.I2C_Read_Repeated(addrs,size) 33 | def write_i2c_block_data(self, addrs,cmd,vals): 34 | self.mcp2221.I2C_Write(addrs,[cmd,vals]) 35 | def reset(self): 36 | self.mcp2221.Reset() 37 | -------------------------------------------------------------------------------- /PyMCP2221A/SMBus.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | from PyMCP2221A import PyMCP2221A 6 | import time 7 | 8 | 9 | # -------------------------------------------------------------# 10 | # SMBus (system management bus) function compatible function # 11 | # -------------------------------------------------------------# 12 | class SMBus: 13 | def __init__(self, VID=0x04D8, PID=0x00DD, devnum=0): 14 | self.mcp2221 = PyMCP2221A.PyMCP2221A(VID, PID, devnum) 15 | self.mcp2221.I2C_Init() 16 | 17 | def read_byte(self, addrs): 18 | return self.mcp2221.I2C_Read(addrs, 1)[0] 19 | 20 | def write_byte(self, addrs, val): 21 | self.mcp2221.I2C_Write(addrs, [val]) 22 | 23 | def read_byte_data(self, addrs, cmd): 24 | self.mcp2221.I2C_Write_No_Stop(addrs, [cmd]) 25 | return self.mcp2221.I2C_Read_Repeated(addrs, 1)[0] 26 | 27 | def write_byte_data(self, addrs, cmd, val): 28 | self.mcp2221.I2C_Write(addrs, [cmd, val]) 29 | 30 | def read_word_data(self, addrs, cmd): 31 | self.mcp2221.I2C_Write_No_Stop(addrs, [cmd]) 32 | tmp = self.mcp2221.I2C_Read_Repeated(addrs, 2) 33 | return tmp[0] | tmp[1] << 8 34 | 35 | def write_word_data(self, addrs, cmd, val): 36 | self.mcp2221.I2C_Write(addrs, [cmd, val & 0x00FF, (val & 0xFF00) >> 8]) 37 | 38 | def read_i2c_block_data(self, addrs, cmd, size): 39 | self.mcp2221.I2C_Write_No_Stop(addrs, [cmd]) 40 | return self.mcp2221.I2C_Read_Repeated(addrs, size) 41 | 42 | def write_i2c_block_data(self, addrs, cmd, vals): 43 | vals.insert(0, cmd) # Insert the CMD into the beginning of the vals LIST. 44 | self.mcp2221.I2C_Write(addrs, vals) 45 | 46 | def reset(self): 47 | self.mcp2221.Reset() 48 | -------------------------------------------------------------------------------- /pypi/main/README.rst: -------------------------------------------------------------------------------- 1 | ===================================================== 2 | PyMCP2221A 3 | ===================================================== 4 | 5 | What is. 6 | ---------------------------------------------------- 7 | 8 | This is a Microchip MCP2221(A) HID Library in python. 9 | 10 | MCP2221 & MCP2221A work in Python. 11 | 12 | 13 | Install 14 | ---------------------------------------------------- 15 | 16 | This library uses hitapi. 17 | 18 | pip install hidapi 19 | 20 | https://github.com/trezor/cython-hidapi 21 | 22 | PyMCP2221A Install 23 | 24 | pip install PyMCP2221A 25 | 26 | 27 | Sample 28 | ---------------------------------------------------- 29 | 30 | from PyMCP2221A import PyMCP2221A 31 | 32 | mcp2221 = PyMCP2221A.PyMCP2221A() 33 | 34 | and More. SMBus (system management bus) compatible function 35 | 36 | from PyMCP2221A import SMBus 37 | 38 | bus = SMBus.SMBus() 39 | 40 | 41 | Setup 42 | ---------------------------------------------------- 43 | 44 | .. image:: ./img/mcp2221.PNG 45 | 46 | 47 | Example 48 | ---------------------------------------------------- 49 | 50 | - MCP2221 ADC : OK : 51 | 52 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_ADC.py 53 | 54 | - MCP2221 DAC : OK : 55 | 56 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_DAC.py 57 | 58 | - MCP2221 GPIO : OK : 59 | 60 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_GPIO.py 61 | 62 | - MCP2221 Interrupt : No : 63 | 64 | - MCP2221 Clock : OK : 65 | 66 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_ClockOUT.py 67 | 68 | - MCP2221 I2C : OK : 69 | 70 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_i2cdetect.py 71 | 72 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_EEPROM_WriteReadTest.py 73 | 74 | 75 | 76 | License 77 | ---------------------------------------------------- 78 | 79 | The MIT License (MIT) Copyright (c) 2017 Yuta Kitagami (kitagami@artifactnoise.com,@nonnoise) 80 | -------------------------------------------------------------------------------- /pypi/armv7l/README.rst: -------------------------------------------------------------------------------- 1 | ===================================================== 2 | PyMCP2221A 3 | ===================================================== 4 | 5 | What is. 6 | ---------------------------------------------------- 7 | 8 | This is a Microchip MCP2221(A) HID Library in python. 9 | 10 | MCP2221 & MCP2221A work in Python. 11 | 12 | 13 | Install 14 | ---------------------------------------------------- 15 | 16 | This library uses hitapi. 17 | 18 | pip install hidapi 19 | 20 | https://github.com/trezor/cython-hidapi 21 | 22 | PyMCP2221A Install 23 | 24 | pip install PyMCP2221A 25 | 26 | Sample 27 | ---------------------------------------------------- 28 | 29 | from PyMCP2221A import PyMCP2221A 30 | 31 | mcp2221 = PyMCP2221A.PyMCP2221A() 32 | 33 | and More. SMBus (system management bus) compatible function 34 | ---------------------------------------------------- 35 | 36 | from PyMCP2221A import SMBus 37 | 38 | bus = SMBus.SMBus() 39 | 40 | 41 | Setup 42 | ---------------------------------------------------- 43 | 44 | .. image:: ./img/mcp2221.PNG 45 | 46 | Example 47 | ---------------------------------------------------- 48 | 49 | - MCP2221 ADC : OK : 50 | 51 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_ADC.py 52 | 53 | - MCP2221 DAC : OK : 54 | 55 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_DAC.py 56 | 57 | - MCP2221 GPIO : OK : 58 | 59 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_GPIO.py 60 | 61 | - MCP2221 Interrupt : No : 62 | 63 | - MCP2221 Clock : OK : 64 | 65 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_ClockOUT.py 66 | 67 | - MCP2221 I2C : OK : 68 | 69 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_i2cdetect.py 70 | 71 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_EEPROM_WriteReadTest.py 72 | 73 | 74 | 75 | License 76 | ---------------------------------------------------- 77 | 78 | The MIT License (MIT) Copyright (c) 2017 Yuta Kitagami (kitagami@artifactnoise.com,@nonnoise) 79 | -------------------------------------------------------------------------------- /README_JP.rst: -------------------------------------------------------------------------------- 1 | ===================================================== 2 | PyMCP2221A 3 | ===================================================== 4 | 5 | これは何ですか? 6 | ---------------------------------------------------- 7 | 8 | これはMCP2221(A)のHIDを使ったPythonライブラリーです。 9 | 10 | MCP2221 と MCP2221A で動作します。 11 | 12 | 13 | 14 | インストールの仕方 15 | ---------------------------------------------------- 16 | 17 | PyMCP2221A Install 18 | 19 | pip install PyMCP2221A 20 | 21 | or 22 | 23 | git clone https://github.com/nonNoise/PyMCP2221A.git 24 | 25 | cd pypi 26 | 27 | sudo python setup.py build 28 | 29 | sudo python setup.py install 30 | 31 | 32 | 33 | Sample 34 | ---------------------------------------------------- 35 | 36 | from PyMCP2221A import PyMCP2221A 37 | 38 | mcp2221 = PyMCP2221A.PyMCP2221A() 39 | 40 | and More. SMBus (system management bus) compatible function 41 | ---------------------------------------------------- 42 | 43 | from PyMCP2221A import SMBus 44 | 45 | bus = SMBus.SMBus() 46 | 47 | 48 | Setup 49 | ---------------------------------------------------- 50 | 51 | .. image:: ./img/mcp2221.PNG 52 | 53 | Example 54 | ---------------------------------------------------- 55 | 56 | - MCP2221 ADC : OK : 57 | 58 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_ADC.py 59 | 60 | - MCP2221 DAC : OK : 61 | 62 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_DAC.py 63 | 64 | - MCP2221 GPIO : OK : 65 | 66 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_GPIO.py 67 | 68 | - MCP2221 Interrupt : No : 69 | 70 | - MCP2221 Clock : OK : 71 | 72 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_ClockOUT.py 73 | 74 | - MCP2221 I2C : OK : 75 | 76 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_i2cdetect.py 77 | 78 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_EEPROM_WriteReadTest.py 79 | 80 | 81 | 82 | 83 | License 84 | ---------------------------------------------------- 85 | 86 | The MIT License (MIT) Copyright (c) 2017 Yuta Kitagami (kitagami@artifactnoise.com,@nonnoise) 87 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ===================================================== 2 | PyMCP2221A 3 | ===================================================== 4 | 5 | What is. 6 | ---------------------------------------------------- 7 | 8 | This is a Microchip MCP2221(A) HID Library in python. 9 | 10 | MCP2221 & MCP2221A work in Python. 11 | 12 | | 13 | 14 | 日本語はこちら 15 | 16 | https://github.com/nonNoise/PyMCP2221A/blob/master/README_JP.rst 17 | 18 | Install 19 | ---------------------------------------------------- 20 | 21 | PyMCP2221A Install 22 | 23 | pip install PyMCP2221A 24 | 25 | or 26 | 27 | git clone https://github.com/nonNoise/PyMCP2221A.git 28 | 29 | cd pypi 30 | 31 | sudo python setup.py build 32 | 33 | sudo python setup.py install 34 | 35 | 36 | 37 | Sample 38 | ---------------------------------------------------- 39 | 40 | from PyMCP2221A import PyMCP2221A 41 | 42 | mcp2221 = PyMCP2221A.PyMCP2221A() 43 | 44 | and More. SMBus (system management bus) compatible function 45 | ---------------------------------------------------- 46 | 47 | from PyMCP2221A import SMBus 48 | 49 | bus = SMBus.SMBus() 50 | 51 | 52 | Setup 53 | ---------------------------------------------------- 54 | 55 | .. image:: ./img/mcp2221.PNG 56 | 57 | Example 58 | ---------------------------------------------------- 59 | 60 | - MCP2221 ADC : OK : 61 | 62 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_ADC.py 63 | 64 | - MCP2221 DAC : OK : 65 | 66 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_DAC.py 67 | 68 | - MCP2221 GPIO : OK : 69 | 70 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_GPIO.py 71 | 72 | - MCP2221 Interrupt : No : 73 | 74 | - MCP2221 Clock : OK : 75 | 76 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_ClockOUT.py 77 | 78 | - MCP2221 I2C : OK : 79 | 80 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_i2cdetect.py 81 | 82 | https://github.com/nonNoise/PyMCP2221A/blob/master/example/MCP2221_EEPROM_WriteReadTest.py 83 | 84 | Note you can change the system enviornment variable for I2C read delay if 85 | you are running into I2C problems. 86 | 87 | import os 88 | os.environ["MCP2221_I2C_SLEEP"] = "0.05" 89 | 90 | 91 | 92 | 93 | License 94 | ---------------------------------------------------- 95 | 96 | The MIT License (MIT) Copyright (c) 2017 Yuta Kitagami (kitagami@artifactnoise.com,@nonnoise) 97 | -------------------------------------------------------------------------------- /pypi/armv7l/PyMCP2221A/PyMCP2221A.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | 6 | import hid 7 | # pip install hidapi 8 | # https://github.com/trezor/cython-hidapi 9 | import time 10 | 11 | 12 | class PyMCP2221A: 13 | def __init__(self,VID = 0x04D8,PID = 0x00DD,devnum = 0): 14 | self.mcp2221a = hid.device() 15 | self.mcp2221a.open_path(hid.enumerate(0x04D8, 0x00DD)[devnum]["path"]) 16 | self.CLKDUTY_0 = 0x00 17 | self.CLKDUTY_25 = 0x08 18 | self.CLKDUTY_50 = 0x10 19 | self.CLKDUTY_75 = 0x18 20 | # self.CLKDIV_1 = 0x00 # 48MHz Dont work. 21 | self.CLKDIV_2 = 0x01 # 24MHz 22 | self.CLKDIV_4 = 0x02 # 12MHz 23 | self.CLKDIV_8 = 0x03 # 6MHz 24 | self.CLKDIV_16 = 0x04 # 3MHz 25 | self.CLKDIV_32 = 0x05 # 1.5MHz 26 | self.CLKDIV_64 = 0x06 # 750KHz 27 | self.CLKDIV_128 = 0x07 # 375KHz 28 | ####################################################################### 29 | # HID DeviceDriver Info 30 | ####################################################################### 31 | def DeviceDriverInfo(self): 32 | print("Manufacturer: %s" % self.mcp2221a.get_manufacturer_string()) 33 | print("Product: %s" % self.mcp2221a.get_product_string()) 34 | print("Serial No: %s" % self.mcp2221a.get_serial_number_string()) 35 | 36 | 37 | ####################################################################### 38 | # Command Structure 39 | ####################################################################### 40 | def Command_Structure(self, I2C_Cancel_Bit, I2C_Speed_SetUp_Bit, I2C_Speed_SetVal_Byte): 41 | I2C_Cancel_Bit = 0 42 | I2C_Speed_SetUp_Bit = 0 43 | I2C_Speed_SetVal_Byte = 0 44 | buf = [0x00, 0x10, 0x00, I2C_Cancel_Bit << 4, I2C_Speed_SetUp_Bit << 5, I2C_Speed_SetVal_Byte] 45 | buf = buf + [0 for i in range(65 - len(buf))] 46 | self.mcp2221a.write(buf) 47 | buf = self.mcp2221a.read(65) 48 | 49 | print (chr(buf[46])) 50 | print (chr(buf[47])) 51 | print (chr(buf[48])) 52 | print (chr(buf[49])) 53 | ####################################################################### 54 | # Read Flash Data 55 | ####################################################################### 56 | 57 | def Read_Flash_Data(self, Read_Deta_Setting_Byte): 58 | Read_Deta_Setting_Byte = 0x00 59 | # Read_Chip_Settings = 0x00 60 | # Read_GP_Settings = 0x01 61 | # Read_USB_Manufacturer_Settings = 0x02 62 | # Read_USB_Product_Settings = 0x03 63 | # Read_USB_SerialNum_Settings = 0x04 64 | # Read_Chip_Factory_Settings = 0x05 65 | buf = [0x00, 0xB0, Read_Deta_Setting_Byte] 66 | buf = buf + [0 for i in range(65 - len(buf))] 67 | # print ("Write") 68 | # print (buf) 69 | self.mcp2221a.write(buf) 70 | buf = self.mcp2221a.read(65) 71 | # print ("Read") 72 | # print (buf) 73 | ####################################################################### 74 | # Write Flash Data 75 | ####################################################################### 76 | 77 | def Write_Flash_Data(self, data): 78 | pass 79 | # Write_Deta_Setting_Byte = 0x00 80 | # Write_Chip_Settings = 0x00 81 | # Write_GP_Settings = 0x01 82 | # Write_USB_Manufacturer_Settings = 0x02 83 | # Write_USB_Product_Settings = 0x03 84 | # Write_USB_SerialNum_Settings = 0x04 85 | # buf = [0x00,0xB1,Write_Deta_Setting_Byte] 86 | # buf = buf + [0 for i in range(65-len(buf))] 87 | # !!!! Be careful when making changes !!!! 88 | # buf[6+1] = 0xD8 # VID (Lower) 89 | # buf[7+1] = 0x04 # VID (Higher) 90 | # buf[8+1] = 0xDD # PID (Lower) 91 | # buf[9+1] = 0x00 # PID (Higher) 92 | 93 | # print ("Write") 94 | # print (buf) 95 | # h.write(buf) 96 | # buf = h.read(65) 97 | # print ("Read") 98 | # print (buf) 99 | 100 | ####################################################################### 101 | # GPIO Init 102 | ####################################################################### 103 | def GPIO_Init(self): 104 | buf = [0x00, 0x61] 105 | buf = buf + [0 for i in range(65 - len(buf))] 106 | self.mcp2221a.write(buf) 107 | rbuf = self.mcp2221a.read(65) 108 | 109 | buf = [0x00, 0x60] 110 | buf = buf + [0 for i in range(65 - len(buf))] 111 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 112 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 113 | buf[4 + 1] = 0x00 # Set DAC output value 114 | buf[5 + 1] = 0x00 # ADC Voltage Reference 115 | # buf[6+1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 116 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 117 | # datasheet says this should be 1, but should actually be 0x80 118 | 119 | self.GPIO_0_BIT = (rbuf[22 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 120 | self.GPIO_0_DIR = (rbuf[22 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 121 | self.GPIO_0_MODE = rbuf[22 + 1] & 0x07 # GPIO MODE = 0x00 122 | self.GPIO_1_BIT = (rbuf[23 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 123 | self.GPIO_1_DIR = (rbuf[23 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 124 | self.GPIO_1_MODE = rbuf[23 + 1] & 0x07 # GPIO MODE = 0x00 125 | self.GPIO_2_BIT = (rbuf[24 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 126 | self.GPIO_2_DIR = (rbuf[24 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 127 | self.GPIO_2_MODE = rbuf[24 + 1] & 0x07 # GPIO MODE = 0x00 128 | self.GPIO_3_BIT = (rbuf[25 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 129 | self.GPIO_3_DIR = (rbuf[25 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 130 | self.GPIO_3_MODE = rbuf[25 + 1] & 0x07 # GPIO MODE = 0x00 131 | 132 | # for(i in range(64)): 133 | # buf[i] = rbuf[i] | buf[i] 134 | self.mcp2221a.write(buf) 135 | buf = self.mcp2221a.read(65) 136 | 137 | 138 | ####################################################################### 139 | # GPIO Write command 140 | ####################################################################### 141 | def GPIO_Write(self): 142 | buf = [0x00, 0x61] 143 | buf = buf + [0 for i in range(65 - len(buf))] 144 | self.mcp2221a.write(buf) 145 | rbuf = self.mcp2221a.read(65) 146 | 147 | buf = [0x00, 0x60] 148 | buf = buf + [0 for i in range(65 - len(buf))] 149 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 150 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 151 | # buf[4+1] = 0x00 # Set DAC output value 152 | # buf[5+1] = 0x00 # ADC Voltage Reference 153 | # buf[6+1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 154 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 155 | # datasheet says this should be 1, but should actually be 0x80 156 | 157 | buf[8 + 1] = self.GPIO_0_BIT << 4 | self.GPIO_0_DIR << 3 | self.GPIO_0_MODE # GP0 settings 158 | buf[9 + 1] = self.GPIO_1_BIT << 4 | self.GPIO_1_DIR << 3 | self.GPIO_1_MODE # GP0 settings 159 | buf[10 + 1] = self.GPIO_2_BIT << 4 | self.GPIO_2_DIR << 3 | self.GPIO_2_MODE # GP0 settings 160 | buf[11 + 1] = self.GPIO_3_BIT << 4 | self.GPIO_3_DIR << 3 | self.GPIO_3_MODE # GP0 settings 161 | # print (buf) 162 | # for(i in range(64)): 163 | # buf[i] = rbuf[i] | buf[i] 164 | self.mcp2221a.write(buf) 165 | self.mcp2221a.read(65) 166 | 167 | ####################################################################### 168 | # Read GPIO Data command 169 | ####################################################################### 170 | def GPIO_Read(self): 171 | buf = [0x00, 0x51] 172 | buf = buf + [0 for i in range(65 - len(buf))] 173 | self.mcp2221a.write(buf) 174 | buf = self.mcp2221a.read(65) 175 | self.GPIO_0_INPUT = buf[2] 176 | self.GPIO_0_DIR = buf[3] 177 | self.GPIO_1_INPUT = buf[4] 178 | self.GPIO_1_DIR = buf[5] 179 | self.GPIO_2_INPUT = buf[6] 180 | self.GPIO_2_DIR = buf[7] 181 | self.GPIO_3_INPUT = buf[8] 182 | self.GPIO_3_DIR = buf[9] 183 | 184 | ####################################################################### 185 | # GPIO Outpu/Input Data 186 | ####################################################################### 187 | def GPIO_0_Output(self, bit): 188 | self.GPIO_0_BIT = bit # 1:Hi 0:LOW 189 | self.GPIO_0_DIR = 0 # 0:OutPut 1:Input 190 | self.GPIO_0_MODE = 0 # 0:GPIO 191 | self.GPIO_Write() 192 | 193 | def GPIO_0_InputMode(self): 194 | self.GPIO_0_DIR = 1 # 0:OutPut 1:Input 195 | self.GPIO_Write() 196 | 197 | def GPIO_0_OutputMode(self): 198 | self.GPIO_0_DIR = 0 # 0:OutPut 1:Input 199 | self.GPIO_Write() 200 | 201 | def GPIO_0_Input(self): 202 | self.GPIO_Read() 203 | return self.GPIO_0_INPUT, self.GPIO_0_DIR 204 | 205 | def GPIO_1_Output(self, bit): 206 | self.GPIO_1_BIT = bit # 1:Hi 0:LOW 207 | self.GPIO_1_DIR = 0 # 0:OutPut 1:Input 208 | self.GPIO_1_MODE = 0 # 0:GPIO 209 | self.GPIO_Write() 210 | 211 | def GPIO_1_InputMode(self): 212 | self.GPIO_1_DIR = 1 # 0:OutPut 1:Input 213 | self.GPIO_Write() 214 | 215 | def GPIO_1_OutputMode(self): 216 | self.GPIO_1_DIR = 0 # 0:OutPut 1:Input 217 | self.GPIO_Write() 218 | 219 | def GPIO_1_Input(self): 220 | self.GPIO_Read() 221 | return self.GPIO_1_INPUT, self.GPIO_1_DIR 222 | 223 | def GPIO_2_Output(self, bit): 224 | self.GPIO_2_BIT = bit # 1:Hi 0:LOW 225 | self.GPIO_2_DIR = 0 # 0:OutPut 1:Input 226 | self.GPIO_2_MODE = 0 # 0:GPIO 227 | self.GPIO_Write() 228 | 229 | def GPIO_2_InputMode(self): 230 | self.GPIO_2_DIR = 1 # 0:OutPut 1:Input 231 | self.GPIO_Write() 232 | 233 | def GPIO_2_OutputMode(self): 234 | self.GPIO_2_DIR = 0 # 0:OutPut 1:Input 235 | self.GPIO_Write() 236 | 237 | def GPIO_2_Input(self): 238 | self.GPIO_Read() 239 | return self.GPIO_2_INPUT, self.GPIO_2_DIR 240 | 241 | def GPIO_3_Output(self, bit): 242 | self.GPIO_3_BIT = bit # 1:Hi 0:LOW 243 | self.GPIO_3_DIR = 0 # 0:OutPut 1:Input 244 | self.GPIO_3_MODE = 0 # 0:GPIO 245 | self.GPIO_Write() 246 | 247 | def GPIO_3_InputMode(self): 248 | self.GPIO_3_DIR = 1 # 0:OutPut 1:Input 249 | self.GPIO_Write() 250 | 251 | def GPIO_3_OutputMode(self): 252 | self.GPIO_3_DIR = 0 # 0:OutPut 1:Input 253 | self.GPIO_Write() 254 | 255 | def GPIO_3_Input(self): 256 | self.GPIO_Read() 257 | return self.GPIO_3_INPUT, self.GPIO_3_DIR 258 | 259 | 260 | ####################################################################### 261 | # Clock Out Value & Duty 262 | ####################################################################### 263 | def ClockOut(self, duty, value): 264 | buf = [0x00, 0x61] 265 | buf = buf + [0 for i in range(65 - len(buf))] 266 | self.mcp2221a.write(buf) 267 | rbuf = self.mcp2221a.read(65) 268 | 269 | buf = [0x00, 0x60] 270 | buf = buf + [0 for i in range(65 - len(buf))] 271 | buf[2 + 1] = 0x80 | duty | (0x07 & value) # Clock Output Divider value 272 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 273 | buf[4 + 1] = 0x00 # Set DAC output value 274 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 275 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 276 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 277 | # datasheet says this should be 1, but should actually be 0x80 278 | buf[8 + 1] = rbuf[22] # GP0 settings 279 | buf[9 + 1] = 0x01 # GP1 settings 280 | buf[10 + 1] = rbuf[24] # GP2 settings 281 | buf[11 + 1] = rbuf[25] # GP3 settings 282 | self.mcp2221a.write(buf) 283 | buf = self.mcp2221a.read(65) 284 | 285 | ####################################################################### 286 | # ADC 1 287 | ####################################################################### 288 | def ADC_1_Init(self): 289 | buf = [0x00, 0x61] 290 | buf = buf + [0 for i in range(65 - len(buf))] 291 | self.mcp2221a.write(buf) 292 | rbuf = self.mcp2221a.read(65) 293 | 294 | buf = [0x00, 0x60] 295 | buf = buf + [0 for i in range(65 - len(buf))] 296 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 297 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 298 | buf[4 + 1] = 0x00 # Set DAC output value 299 | buf[5 + 1] = 0x00 # ADC Voltage Reference 300 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 301 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 302 | # datasheet says this should be 1, but should actually be 0x80 303 | buf[8 + 1] = rbuf[22] # GP0 settings 304 | buf[9 + 1] = 0x02 # GP1 settings 305 | buf[10 + 1] = rbuf[24] # GP2 settings 306 | buf[11 + 1] = rbuf[25] # GP3 settings 307 | self.mcp2221a.write(buf) 308 | buf = self.mcp2221a.read(65) 309 | ####################################################################### 310 | # ADC 2 311 | ####################################################################### 312 | 313 | def ADC_2_Init(self): 314 | buf = [0x00, 0x61] 315 | buf = buf + [0 for i in range(65 - len(buf))] 316 | self.mcp2221a.write(buf) 317 | rbuf = self.mcp2221a.read(65) 318 | 319 | buf = [0x00, 0x60] 320 | buf = buf + [0 for i in range(65 - len(buf))] 321 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 322 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 323 | buf[4 + 1] = 0x00 # Set DAC output value 324 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 325 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 326 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 327 | # datasheet says this should be 1, but should actually be 0x80 328 | buf[8 + 1] = rbuf[22] # GP0 settings 329 | buf[9 + 1] = rbuf[23] # GP1 settings 330 | buf[10 + 1] = 0x02 # GP2 settings 331 | buf[11 + 1] = rbuf[25] # GP3 settings 332 | self.mcp2221a.write(buf) 333 | buf = self.mcp2221a.read(65) 334 | ####################################################################### 335 | # ADC 3 336 | ####################################################################### 337 | 338 | def ADC_3_Init(self): 339 | buf = [0x00, 0x61] 340 | buf = buf + [0 for i in range(65 - len(buf))] 341 | self.mcp2221a.write(buf) 342 | rbuf = self.mcp2221a.read(65) 343 | 344 | buf = [0x00, 0x60] 345 | buf = buf + [0 for i in range(65 - len(buf))] 346 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 347 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 348 | buf[4 + 1] = 0x00 # Set DAC output value 349 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 350 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 351 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 352 | # datasheet says this should be 1, but should actually be 0x80 353 | buf[8 + 1] = rbuf[22] # GP0 settings 354 | buf[9 + 1] = rbuf[23] # GP1 settings 355 | buf[10 + 1] = rbuf[24] # GP2 settings 356 | buf[11 + 1] = 0x02 # GP3 settings 357 | self.mcp2221a.write(buf) 358 | buf = self.mcp2221a.read(65) 359 | ####################################################################### 360 | # ADC Deta Get 361 | ####################################################################### 362 | 363 | def ADC_DataRead(self): 364 | buf = [0x00, 0x10] 365 | buf = buf + [0 for i in range(65 - len(buf))] 366 | self.mcp2221a.write(buf) 367 | buf = self.mcp2221a.read(65) 368 | # for i in range(len(buf)): 369 | # print ("[%d]: 0x{:02x}".format(buf[i]) % (i)) 370 | self.ADC_1_data = buf[50] | (buf[51] << 8) # ADC Data (16-bit) values 371 | self.ADC_2_data = buf[52] | (buf[53] << 8) # ADC Data (16-bit) values 372 | self.ADC_3_data = buf[54] | (buf[55] << 8) # ADC Data (16-bit) values 373 | 374 | ####################################################################### 375 | # DAC 1 376 | ####################################################################### 377 | def DAC_1_Init(self): 378 | buf = [0x00, 0x61] 379 | buf = buf + [0 for i in range(65 - len(buf))] 380 | self.mcp2221a.write(buf) 381 | rbuf = self.mcp2221a.read(65) 382 | 383 | buf = [0x00, 0x60] 384 | buf = buf + [0 for i in range(65 - len(buf))] 385 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 386 | buf[3 + 1] = 0x00 # DAC Voltage Reference 387 | buf[4 + 1] = 0x00 # Set DAC output value 388 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 389 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 390 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 391 | # datasheet says this should be 1, but should actually be 0x80 392 | buf[8 + 1] = rbuf[22] # GP0 settings 393 | buf[9 + 1] = rbuf[23] # GP1 settings 394 | buf[10 + 1] = 0x03 # GP2 settings 395 | buf[11 + 1] = rbuf[25] # GP3 settings 396 | self.mcp2221a.write(buf) 397 | buf = self.mcp2221a.read(65) 398 | ####################################################################### 399 | # DAC 2 400 | ####################################################################### 401 | 402 | def DAC_2_Init(self): 403 | buf = [0x00, 0x61] 404 | buf = buf + [0 for i in range(65 - len(buf))] 405 | self.mcp2221a.write(buf) 406 | rbuf = self.mcp2221a.read(65) 407 | 408 | buf = [0x00, 0x60] 409 | buf = buf + [0 for i in range(65 - len(buf))] 410 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 411 | buf[3 + 1] = 0x00 # DAC Voltage Reference 412 | buf[4 + 1] = 0x00 # Set DAC output value 413 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 414 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 415 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 416 | # datasheet says this should be 1, but should actually be 0x80 417 | buf[8 + 1] = rbuf[22] # GP0 settings 418 | buf[9 + 1] = rbuf[23] # GP1 settings 419 | buf[10 + 1] = rbuf[24] # GP2 settings 420 | buf[11 + 1] = 0x03 # GP3 settings 421 | self.mcp2221a.write(buf) 422 | buf = self.mcp2221a.read(65) 423 | ####################################################################### 424 | # DAC Output 425 | ####################################################################### 426 | 427 | def DAC_Datawrite(self, value): 428 | buf = [0x00, 0x61] 429 | buf = buf + [0 for i in range(65 - len(buf))] 430 | self.mcp2221a.write(buf) 431 | rbuf = self.mcp2221a.read(65) 432 | 433 | buf = [0x00, 0x60] 434 | buf = buf + [0 for i in range(65 - len(buf))] 435 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 436 | buf[3 + 1] = 0x00 # DAC Voltage Reference 437 | buf[4 + 1] = 0x80 | (0x0F & value) # Set DAC output value 438 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 439 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 440 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 441 | # datasheet says this should be 1, but should actually be 0x80 442 | buf[8 + 1] = rbuf[22] # GP0 settings 443 | buf[9 + 1] = rbuf[23] # GP1 settings 444 | buf[10 + 1] = rbuf[24] # GP2 settings 445 | buf[11 + 1] = rbuf[25] # GP3 settings 446 | self.mcp2221a.write(buf) 447 | buf = self.mcp2221a.read(65) 448 | 449 | 450 | ####################################################################### 451 | # I2C Init 452 | ####################################################################### 453 | def I2C_Init(self, speed=100000): # speed = 100000 454 | 455 | buf = [0x00, 0x10] 456 | buf = buf + [0 for i in range(65 - len(buf))] 457 | buf[2 + 1] = 0x00 # Cancel current I2C/SMBus transfer (sub-command) 458 | buf[3 + 1] = 0x20 # Set I2C/SMBus communication speed (sub-command) 459 | # The I2C/SMBus system clock divider that will be used to establish the communication speed 460 | buf[4 + 1] = int((12000000 / speed) - 3) 461 | self.mcp2221a.write(buf) 462 | rbuf = self.mcp2221a.read(65) 463 | # print("Init") 464 | if(rbuf[22] == 0): 465 | print("SCL is low.") 466 | exit() 467 | return -1 468 | if(rbuf[23] == 0): 469 | print("SDA is low.") 470 | exit() 471 | return -1 472 | 473 | # time.sleep(0.001) 474 | 475 | ####################################################################### 476 | # I2C State Check 477 | ####################################################################### 478 | def I2C_State_Check(self): 479 | buf = [0x00, 0x10] 480 | buf = buf + [0 for i in range(65 - len(buf))] 481 | self.mcp2221a.write(buf) 482 | rbuf = self.mcp2221a.read(65) 483 | return rbuf[8] 484 | ####################################################################### 485 | # I2C Cancel 486 | ####################################################################### 487 | 488 | def I2C_Cancel(self): 489 | buf = [0x00, 0x10] 490 | buf = buf + [0 for i in range(65 - len(buf))] 491 | buf[2 + 1] = 0x10 # Cancel current I2C/SMBus transfer (sub-command) 492 | self.mcp2221a.write(buf) 493 | self.mcp2221a.read(65) 494 | # time.sleep(0.1) 495 | 496 | ####################################################################### 497 | # I2C Write 498 | ####################################################################### 499 | def I2C_Write(self, addrs, data): 500 | """ Writes a block of data with Start and Stop c condition on bus 501 | :param int addrs: 8-bit I2C slave address 502 | :param list data: list of int 503 | 504 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.5 505 | """ 506 | buf = [0x00, 0x90] 507 | self._i2c_write(addrs, data, buf) 508 | 509 | def I2C_Write_Repeated(self, addrs, data): 510 | """ Writes a block of data with Repeated Start and Stop conditions on bus 511 | :param int addrs: 8-bit I2C slave address 512 | :param list data: list of int 513 | 514 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.6 515 | """ 516 | buf = [0x00, 0x92] 517 | self._i2c_write(addrs, data, buf) 518 | 519 | def I2C_Write_No_Stop(self, addrs, data): 520 | """ Writes a block of data with Start condition on bus 521 | :param int addrs: 8-bit I2C slave address 522 | :param list data: list of int 523 | 524 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.7 525 | """ 526 | buf = [0x00, 0x94] 527 | self._i2c_write(addrs, data, buf) 528 | 529 | def _i2c_write(self, addrs, data, buf): 530 | buf = buf + [0 for i in range(65 - len(buf))] 531 | buf[1 + 1] = (len(data) & 0x00FF) # Cancel current I2C/SMBus transfer (sub-command) 532 | buf[2 + 1] = (len(data) & 0xFF00) >> 8 # Set I2C/SMBus communication speed (sub-command) 533 | # The I2C/SMBus system clock divider that will be used to establish the communication speed 534 | buf[3 + 1] = 0xFF & (addrs << 1) 535 | for i in range(len(data)): 536 | # print ("{:d}: 0x{:02x}".format(i,data[i])) 537 | buf[4 + 1 + i] = data[i] # The I2C/SMBus system clock divider that will be used to establish the communication speed 538 | self.mcp2221a.write(buf) 539 | rbuf = self.mcp2221a.read(65) 540 | time.sleep(0.008) 541 | 542 | 543 | ####################################################################### 544 | # I2C Read 545 | ####################################################################### 546 | def I2C_Read(self, addrs, size): 547 | """ Reads a block of data with Start and Stop conditions on bus 548 | :param int addrs: 8-bit I2C slave address 549 | :param int size: size of read out in bytes 550 | 551 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.8 552 | """ 553 | buf = [0x00, 0x91] 554 | return self._i2c_read(addrs, size, buf) 555 | 556 | def I2C_Read_Repeated(self, addrs, size): 557 | """ Reads a block of data with Repeated Start and Stop conditions on bus 558 | :param int addrs: 8-bit I2C slave address 559 | :param int size: size of read out in bytes 560 | 561 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.9 562 | """ 563 | buf = [0x00, 0x93] 564 | return self._i2c_read(addrs, size, buf) 565 | 566 | def _i2c_read(self, addrs, size, buf): 567 | buf = buf + [0 for i in range(65 - len(buf))] 568 | 569 | buf[1 + 1] = (size & 0x00FF) # Read LEN 570 | buf[2 + 1] = (size & 0xFF00) >> 8 # Read LEN 571 | buf[3 + 1] = 0xFF & (addrs << 1) # addrs 572 | self.mcp2221a.write(buf) 573 | rbuf = self.mcp2221a.read(65) 574 | if (rbuf[1] != 0x00): 575 | # print("[0x91:0x{:02x},0x{:02x},0x{:02x}]".format(rbuf[1],rbuf[2],rbuf[3])) 576 | self.I2C_Cancel() 577 | self.I2C_Init() 578 | return -1 579 | # time.sleep(0.1) 580 | buf = [0x00, 0x40] 581 | buf = buf + [0 for i in range(65 - len(buf))] 582 | buf[1 + 1] = 0x00 583 | buf[2 + 1] = 0x00 584 | buf[3 + 1] = 0x00 585 | self.mcp2221a.write(buf) 586 | rbuf = self.mcp2221a.read(65) 587 | if (rbuf[1] != 0x00): 588 | # print("[0x40:0x{:02x},0x{:02x},0x{:02x}]".format(rbuf[1],rbuf[2],rbuf[3])) 589 | self.I2C_Cancel() 590 | self.I2C_Init() 591 | return -1 592 | if (rbuf[2] == 0x00 and rbuf[3] == 0x00): 593 | self.I2C_Cancel() 594 | self.I2C_Init() 595 | return rbuf[4] 596 | if (rbuf[2] == 0x55 and rbuf[3] == size): 597 | rdata = [0] * size 598 | for i in range(size): 599 | rdata[i] = rbuf[4 + i] 600 | return rdata 601 | 602 | 603 | ####################################################################### 604 | # reset 605 | ####################################################################### 606 | def Reset(self): 607 | print ("Reset") 608 | buf = [0x00, 0x70, 0xAB, 0xCD, 0xEF] 609 | buf = buf + [0 for i in range(65 - len(buf))] 610 | self.mcp2221a.write(buf) 611 | time.sleep(1) 612 | -------------------------------------------------------------------------------- /example/PyMCP2221A/PyMCP2221A.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | 6 | import hid 7 | #import hid 8 | # pip install hidapi 9 | # https://github.com/trezor/cython-hidapi 10 | import time 11 | 12 | 13 | class PyMCP2221A: 14 | def __init__(self,VID = 0x04D8,PID = 0x00DD,devnum = 0): 15 | self.mcp2221a = hid.device() 16 | self.mcp2221a.open_path(hid.enumerate(VID, PID)[devnum]["path"]) 17 | self.CLKDUTY_0 = 0x00 18 | self.CLKDUTY_25 = 0x08 19 | self.CLKDUTY_50 = 0x10 20 | self.CLKDUTY_75 = 0x18 21 | # self.CLKDIV_1 = 0x00 # 48MHz Dont work. 22 | self.CLKDIV_2 = 0x01 # 24MHz 23 | self.CLKDIV_4 = 0x02 # 12MHz 24 | self.CLKDIV_8 = 0x03 # 6MHz 25 | self.CLKDIV_16 = 0x04 # 3MHz 26 | self.CLKDIV_32 = 0x05 # 1.5MHz 27 | self.CLKDIV_64 = 0x06 # 750KHz 28 | self.CLKDIV_128 = 0x07 # 375KHz 29 | ####################################################################### 30 | # HID DeviceDriver Info 31 | ####################################################################### 32 | def DeviceDriverInfo(self): 33 | print("Manufacturer: %s" % self.mcp2221a.get_manufacturer_string()) 34 | print("Product: %s" % self.mcp2221a.get_product_string()) 35 | print("Serial No: %s" % self.mcp2221a.get_serial_number_string()) 36 | 37 | 38 | ####################################################################### 39 | # Command Structure 40 | ####################################################################### 41 | def Command_Structure(self, I2C_Cancel_Bit, I2C_Speed_SetUp_Bit, I2C_Speed_SetVal_Byte): 42 | I2C_Cancel_Bit = 0 43 | I2C_Speed_SetUp_Bit = 0 44 | I2C_Speed_SetVal_Byte = 0 45 | buf = [0x00, 0x10, 0x00, I2C_Cancel_Bit << 4, I2C_Speed_SetUp_Bit << 5, I2C_Speed_SetVal_Byte] 46 | buf = buf + [0 for i in range(65 - len(buf))] 47 | self.mcp2221a.write(buf) 48 | buf = self.mcp2221a.read(65) 49 | 50 | print (chr(buf[46])) 51 | print (chr(buf[47])) 52 | print (chr(buf[48])) 53 | print (chr(buf[49])) 54 | ####################################################################### 55 | # Read Flash Data 56 | ####################################################################### 57 | 58 | def Read_Flash_Data(self, Read_Deta_Setting_Byte): 59 | Read_Deta_Setting_Byte = 0x00 60 | # Read_Chip_Settings = 0x00 61 | # Read_GP_Settings = 0x01 62 | # Read_USB_Manufacturer_Settings = 0x02 63 | # Read_USB_Product_Settings = 0x03 64 | # Read_USB_SerialNum_Settings = 0x04 65 | # Read_Chip_Factory_Settings = 0x05 66 | buf = [0x00, 0xB0, Read_Deta_Setting_Byte] 67 | buf = buf + [0 for i in range(65 - len(buf))] 68 | # print ("Write") 69 | # print (buf) 70 | self.mcp2221a.write(buf) 71 | buf = self.mcp2221a.read(65) 72 | # print ("Read") 73 | # print (buf) 74 | ####################################################################### 75 | # Write Flash Data 76 | ####################################################################### 77 | 78 | def Write_Flash_Data(self, data): 79 | pass 80 | # Write_Deta_Setting_Byte = 0x00 81 | # Write_Chip_Settings = 0x00 82 | # Write_GP_Settings = 0x01 83 | # Write_USB_Manufacturer_Settings = 0x02 84 | # Write_USB_Product_Settings = 0x03 85 | # Write_USB_SerialNum_Settings = 0x04 86 | # buf = [0x00,0xB1,Write_Deta_Setting_Byte] 87 | # buf = buf + [0 for i in range(65-len(buf))] 88 | # !!!! Be careful when making changes !!!! 89 | # buf[6+1] = 0xD8 # VID (Lower) 90 | # buf[7+1] = 0x04 # VID (Higher) 91 | # buf[8+1] = 0xDD # PID (Lower) 92 | # buf[9+1] = 0x00 # PID (Higher) 93 | 94 | # print ("Write") 95 | # print (buf) 96 | # h.write(buf) 97 | # buf = h.read(65) 98 | # print ("Read") 99 | # print (buf) 100 | 101 | ####################################################################### 102 | # GPIO Init 103 | ####################################################################### 104 | def GPIO_Init(self): 105 | buf = [0x00, 0x61] 106 | buf = buf + [0 for i in range(65 - len(buf))] 107 | self.mcp2221a.write(buf) 108 | rbuf = self.mcp2221a.read(65) 109 | 110 | buf = [0x00, 0x60] 111 | buf = buf + [0 for i in range(65 - len(buf))] 112 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 113 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 114 | buf[4 + 1] = 0x00 # Set DAC output value 115 | buf[5 + 1] = 0x00 # ADC Voltage Reference 116 | # buf[6+1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 117 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 118 | # datasheet says this should be 1, but should actually be 0x80 119 | 120 | self.GPIO_0_BIT = (rbuf[22 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 121 | self.GPIO_0_DIR = (rbuf[22 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 122 | self.GPIO_0_MODE = rbuf[22 + 1] & 0x07 # GPIO MODE = 0x00 123 | self.GPIO_1_BIT = (rbuf[23 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 124 | self.GPIO_1_DIR = (rbuf[23 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 125 | self.GPIO_1_MODE = rbuf[23 + 1] & 0x07 # GPIO MODE = 0x00 126 | self.GPIO_2_BIT = (rbuf[24 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 127 | self.GPIO_2_DIR = (rbuf[24 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 128 | self.GPIO_2_MODE = rbuf[24 + 1] & 0x07 # GPIO MODE = 0x00 129 | self.GPIO_3_BIT = (rbuf[25 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 130 | self.GPIO_3_DIR = (rbuf[25 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 131 | self.GPIO_3_MODE = rbuf[25 + 1] & 0x07 # GPIO MODE = 0x00 132 | 133 | # for(i in range(64)): 134 | # buf[i] = rbuf[i] | buf[i] 135 | self.mcp2221a.write(buf) 136 | buf = self.mcp2221a.read(65) 137 | 138 | 139 | ####################################################################### 140 | # GPIO Write command 141 | ####################################################################### 142 | def GPIO_Write(self): 143 | buf = [0x00, 0x61] 144 | buf = buf + [0 for i in range(65 - len(buf))] 145 | self.mcp2221a.write(buf) 146 | rbuf = self.mcp2221a.read(65) 147 | 148 | buf = [0x00, 0x60] 149 | buf = buf + [0 for i in range(65 - len(buf))] 150 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 151 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 152 | # buf[4+1] = 0x00 # Set DAC output value 153 | # buf[5+1] = 0x00 # ADC Voltage Reference 154 | # buf[6+1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 155 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 156 | # datasheet says this should be 1, but should actually be 0x80 157 | 158 | buf[8 + 1] = self.GPIO_0_BIT << 4 | self.GPIO_0_DIR << 3 | self.GPIO_0_MODE # GP0 settings 159 | buf[9 + 1] = self.GPIO_1_BIT << 4 | self.GPIO_1_DIR << 3 | self.GPIO_1_MODE # GP0 settings 160 | buf[10 + 1] = self.GPIO_2_BIT << 4 | self.GPIO_2_DIR << 3 | self.GPIO_2_MODE # GP0 settings 161 | buf[11 + 1] = self.GPIO_3_BIT << 4 | self.GPIO_3_DIR << 3 | self.GPIO_3_MODE # GP0 settings 162 | # print (buf) 163 | # for(i in range(64)): 164 | # buf[i] = rbuf[i] | buf[i] 165 | self.mcp2221a.write(buf) 166 | self.mcp2221a.read(65) 167 | 168 | ####################################################################### 169 | # Read GPIO Data command 170 | ####################################################################### 171 | def GPIO_Read(self): 172 | buf = [0x00, 0x51] 173 | buf = buf + [0 for i in range(65 - len(buf))] 174 | self.mcp2221a.write(buf) 175 | buf = self.mcp2221a.read(65) 176 | self.GPIO_0_INPUT = buf[2] 177 | self.GPIO_0_DIR = buf[3] 178 | self.GPIO_1_INPUT = buf[4] 179 | self.GPIO_1_DIR = buf[5] 180 | self.GPIO_2_INPUT = buf[6] 181 | self.GPIO_2_DIR = buf[7] 182 | self.GPIO_3_INPUT = buf[8] 183 | self.GPIO_3_DIR = buf[9] 184 | 185 | ####################################################################### 186 | # GPIO Outpu/Input Data 187 | ####################################################################### 188 | def GPIO_0_Output(self, bit): 189 | self.GPIO_0_BIT = bit # 1:Hi 0:LOW 190 | self.GPIO_0_DIR = 0 # 0:OutPut 1:Input 191 | self.GPIO_0_MODE = 0 # 0:GPIO 192 | self.GPIO_Write() 193 | 194 | def GPIO_0_InputMode(self): 195 | self.GPIO_0_DIR = 1 # 0:OutPut 1:Input 196 | self.GPIO_Write() 197 | 198 | def GPIO_0_OutputMode(self): 199 | self.GPIO_0_DIR = 0 # 0:OutPut 1:Input 200 | self.GPIO_Write() 201 | 202 | def GPIO_0_Input(self): 203 | self.GPIO_Read() 204 | return self.GPIO_0_INPUT, self.GPIO_0_DIR 205 | 206 | def GPIO_1_Output(self, bit): 207 | self.GPIO_1_BIT = bit # 1:Hi 0:LOW 208 | self.GPIO_1_DIR = 0 # 0:OutPut 1:Input 209 | self.GPIO_1_MODE = 0 # 0:GPIO 210 | self.GPIO_Write() 211 | 212 | def GPIO_1_InputMode(self): 213 | self.GPIO_1_DIR = 1 # 0:OutPut 1:Input 214 | self.GPIO_Write() 215 | 216 | def GPIO_1_OutputMode(self): 217 | self.GPIO_1_DIR = 0 # 0:OutPut 1:Input 218 | self.GPIO_Write() 219 | 220 | def GPIO_1_Input(self): 221 | self.GPIO_Read() 222 | return self.GPIO_1_INPUT, self.GPIO_1_DIR 223 | 224 | def GPIO_2_Output(self, bit): 225 | self.GPIO_2_BIT = bit # 1:Hi 0:LOW 226 | self.GPIO_2_DIR = 0 # 0:OutPut 1:Input 227 | self.GPIO_2_MODE = 0 # 0:GPIO 228 | self.GPIO_Write() 229 | 230 | def GPIO_2_InputMode(self): 231 | self.GPIO_2_DIR = 1 # 0:OutPut 1:Input 232 | self.GPIO_Write() 233 | 234 | def GPIO_2_OutputMode(self): 235 | self.GPIO_2_DIR = 0 # 0:OutPut 1:Input 236 | self.GPIO_Write() 237 | 238 | def GPIO_2_Input(self): 239 | self.GPIO_Read() 240 | return self.GPIO_2_INPUT, self.GPIO_2_DIR 241 | 242 | def GPIO_3_Output(self, bit): 243 | self.GPIO_3_BIT = bit # 1:Hi 0:LOW 244 | self.GPIO_3_DIR = 0 # 0:OutPut 1:Input 245 | self.GPIO_3_MODE = 0 # 0:GPIO 246 | self.GPIO_Write() 247 | 248 | def GPIO_3_InputMode(self): 249 | self.GPIO_3_DIR = 1 # 0:OutPut 1:Input 250 | self.GPIO_Write() 251 | 252 | def GPIO_3_OutputMode(self): 253 | self.GPIO_3_DIR = 0 # 0:OutPut 1:Input 254 | self.GPIO_Write() 255 | 256 | def GPIO_3_Input(self): 257 | self.GPIO_Read() 258 | return self.GPIO_3_INPUT, self.GPIO_3_DIR 259 | 260 | 261 | ####################################################################### 262 | # Clock Out Value & Duty 263 | ####################################################################### 264 | def ClockOut(self, duty, value): 265 | buf = [0x00, 0x61] 266 | buf = buf + [0 for i in range(65 - len(buf))] 267 | self.mcp2221a.write(buf) 268 | rbuf = self.mcp2221a.read(65) 269 | 270 | buf = [0x00, 0x60] 271 | buf = buf + [0 for i in range(65 - len(buf))] 272 | buf[2 + 1] = 0x80 | duty | (0x07 & value) # Clock Output Divider value 273 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 274 | buf[4 + 1] = 0x00 # Set DAC output value 275 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 276 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 277 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 278 | # datasheet says this should be 1, but should actually be 0x80 279 | buf[8 + 1] = rbuf[22] # GP0 settings 280 | buf[9 + 1] = 0x01 # GP1 settings 281 | buf[10 + 1] = rbuf[24] # GP2 settings 282 | buf[11 + 1] = rbuf[25] # GP3 settings 283 | self.mcp2221a.write(buf) 284 | buf = self.mcp2221a.read(65) 285 | 286 | ####################################################################### 287 | # ADC 1 288 | ####################################################################### 289 | def ADC_1_Init(self): 290 | buf = [0x00, 0x61] 291 | buf = buf + [0 for i in range(65 - len(buf))] 292 | self.mcp2221a.write(buf) 293 | rbuf = self.mcp2221a.read(65) 294 | 295 | buf = [0x00, 0x60] 296 | buf = buf + [0 for i in range(65 - len(buf))] 297 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 298 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 299 | buf[4 + 1] = 0x00 # Set DAC output value 300 | buf[5 + 1] = 0x00 # ADC Voltage Reference 301 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 302 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 303 | # datasheet says this should be 1, but should actually be 0x80 304 | buf[8 + 1] = rbuf[22] # GP0 settings 305 | buf[9 + 1] = 0x02 # GP1 settings 306 | buf[10 + 1] = rbuf[24] # GP2 settings 307 | buf[11 + 1] = rbuf[25] # GP3 settings 308 | self.mcp2221a.write(buf) 309 | buf = self.mcp2221a.read(65) 310 | ####################################################################### 311 | # ADC 2 312 | ####################################################################### 313 | 314 | def ADC_2_Init(self): 315 | buf = [0x00, 0x61] 316 | buf = buf + [0 for i in range(65 - len(buf))] 317 | self.mcp2221a.write(buf) 318 | rbuf = self.mcp2221a.read(65) 319 | 320 | buf = [0x00, 0x60] 321 | buf = buf + [0 for i in range(65 - len(buf))] 322 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 323 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 324 | buf[4 + 1] = 0x00 # Set DAC output value 325 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 326 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 327 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 328 | # datasheet says this should be 1, but should actually be 0x80 329 | buf[8 + 1] = rbuf[22] # GP0 settings 330 | buf[9 + 1] = rbuf[23] # GP1 settings 331 | buf[10 + 1] = 0x02 # GP2 settings 332 | buf[11 + 1] = rbuf[25] # GP3 settings 333 | self.mcp2221a.write(buf) 334 | buf = self.mcp2221a.read(65) 335 | ####################################################################### 336 | # ADC 3 337 | ####################################################################### 338 | 339 | def ADC_3_Init(self): 340 | buf = [0x00, 0x61] 341 | buf = buf + [0 for i in range(65 - len(buf))] 342 | self.mcp2221a.write(buf) 343 | rbuf = self.mcp2221a.read(65) 344 | 345 | buf = [0x00, 0x60] 346 | buf = buf + [0 for i in range(65 - len(buf))] 347 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 348 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 349 | buf[4 + 1] = 0x00 # Set DAC output value 350 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 351 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 352 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 353 | # datasheet says this should be 1, but should actually be 0x80 354 | buf[8 + 1] = rbuf[22] # GP0 settings 355 | buf[9 + 1] = rbuf[23] # GP1 settings 356 | buf[10 + 1] = rbuf[24] # GP2 settings 357 | buf[11 + 1] = 0x02 # GP3 settings 358 | self.mcp2221a.write(buf) 359 | buf = self.mcp2221a.read(65) 360 | ####################################################################### 361 | # ADC Deta Get 362 | ####################################################################### 363 | 364 | def ADC_DataRead(self): 365 | buf = [0x00, 0x10] 366 | buf = buf + [0 for i in range(65 - len(buf))] 367 | self.mcp2221a.write(buf) 368 | buf = self.mcp2221a.read(65) 369 | # for i in range(len(buf)): 370 | # print ("[%d]: 0x{:02x}".format(buf[i]) % (i)) 371 | self.ADC_1_data = buf[50] | (buf[51] << 8) # ADC Data (16-bit) values 372 | self.ADC_2_data = buf[52] | (buf[53] << 8) # ADC Data (16-bit) values 373 | self.ADC_3_data = buf[54] | (buf[55] << 8) # ADC Data (16-bit) values 374 | 375 | ####################################################################### 376 | # DAC 1 377 | ####################################################################### 378 | def DAC_1_Init(self): 379 | buf = [0x00, 0x61] 380 | buf = buf + [0 for i in range(65 - len(buf))] 381 | self.mcp2221a.write(buf) 382 | rbuf = self.mcp2221a.read(65) 383 | 384 | buf = [0x00, 0x60] 385 | buf = buf + [0 for i in range(65 - len(buf))] 386 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 387 | buf[3 + 1] = 0x00 # DAC Voltage Reference 388 | buf[4 + 1] = 0x00 # Set DAC output value 389 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 390 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 391 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 392 | # datasheet says this should be 1, but should actually be 0x80 393 | buf[8 + 1] = rbuf[22] # GP0 settings 394 | buf[9 + 1] = rbuf[23] # GP1 settings 395 | buf[10 + 1] = 0x03 # GP2 settings 396 | buf[11 + 1] = rbuf[25] # GP3 settings 397 | self.mcp2221a.write(buf) 398 | buf = self.mcp2221a.read(65) 399 | ####################################################################### 400 | # DAC 2 401 | ####################################################################### 402 | 403 | def DAC_2_Init(self): 404 | buf = [0x00, 0x61] 405 | buf = buf + [0 for i in range(65 - len(buf))] 406 | self.mcp2221a.write(buf) 407 | rbuf = self.mcp2221a.read(65) 408 | 409 | buf = [0x00, 0x60] 410 | buf = buf + [0 for i in range(65 - len(buf))] 411 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 412 | buf[3 + 1] = 0x00 # DAC Voltage Reference 413 | buf[4 + 1] = 0x00 # Set DAC output value 414 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 415 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 416 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 417 | # datasheet says this should be 1, but should actually be 0x80 418 | buf[8 + 1] = rbuf[22] # GP0 settings 419 | buf[9 + 1] = rbuf[23] # GP1 settings 420 | buf[10 + 1] = rbuf[24] # GP2 settings 421 | buf[11 + 1] = 0x03 # GP3 settings 422 | self.mcp2221a.write(buf) 423 | buf = self.mcp2221a.read(65) 424 | ####################################################################### 425 | # DAC Output 426 | ####################################################################### 427 | 428 | def DAC_Datawrite(self, value): 429 | buf = [0x00, 0x61] 430 | buf = buf + [0 for i in range(65 - len(buf))] 431 | self.mcp2221a.write(buf) 432 | rbuf = self.mcp2221a.read(65) 433 | 434 | buf = [0x00, 0x60] 435 | buf = buf + [0 for i in range(65 - len(buf))] 436 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 437 | buf[3 + 1] = 0x00 # DAC Voltage Reference 438 | buf[4 + 1] = 0x80 | (0x0F & value) # Set DAC output value 439 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 440 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 441 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 442 | # datasheet says this should be 1, but should actually be 0x80 443 | buf[8 + 1] = rbuf[22] # GP0 settings 444 | buf[9 + 1] = rbuf[23] # GP1 settings 445 | buf[10 + 1] = rbuf[24] # GP2 settings 446 | buf[11 + 1] = rbuf[25] # GP3 settings 447 | self.mcp2221a.write(buf) 448 | buf = self.mcp2221a.read(65) 449 | 450 | 451 | ####################################################################### 452 | # I2C Init 453 | ####################################################################### 454 | def I2C_Init(self, speed=100000): # speed = 100000 455 | 456 | buf = [0x00, 0x10] 457 | buf = buf + [0 for i in range(65 - len(buf))] 458 | buf[2 + 1] = 0x00 # Cancel current I2C/SMBus transfer (sub-command) 459 | buf[3 + 1] = 0x20 # Set I2C/SMBus communication speed (sub-command) 460 | # The I2C/SMBus system clock divider that will be used to establish the communication speed 461 | buf[4 + 1] = int((12000000 / speed) - 3) 462 | self.mcp2221a.write(buf) 463 | rbuf = self.mcp2221a.read(65) 464 | # print("Init") 465 | if(rbuf[22] == 0): 466 | print("SCL is low.") 467 | exit() 468 | return -1 469 | if(rbuf[23] == 0): 470 | print("SDA is low.") 471 | exit() 472 | return -1 473 | 474 | # time.sleep(0.001) 475 | 476 | ####################################################################### 477 | # I2C State Check 478 | ####################################################################### 479 | def I2C_State_Check(self): 480 | buf = [0x00, 0x10] 481 | buf = buf + [0 for i in range(65 - len(buf))] 482 | self.mcp2221a.write(buf) 483 | rbuf = self.mcp2221a.read(65) 484 | return rbuf[8] 485 | ####################################################################### 486 | # I2C Cancel 487 | ####################################################################### 488 | 489 | def I2C_Cancel(self): 490 | buf = [0x00, 0x10] 491 | buf = buf + [0 for i in range(65 - len(buf))] 492 | buf[2 + 1] = 0x10 # Cancel current I2C/SMBus transfer (sub-command) 493 | self.mcp2221a.write(buf) 494 | self.mcp2221a.read(65) 495 | # time.sleep(0.1) 496 | 497 | ####################################################################### 498 | # I2C Write 499 | ####################################################################### 500 | def I2C_Write(self, addrs, data): 501 | """ Writes a block of data with Start and Stop c condition on bus 502 | :param int addrs: 8-bit I2C slave address 503 | :param list data: list of int 504 | 505 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.5 506 | """ 507 | buf = [0x00, 0x90] 508 | self._i2c_write(addrs, data, buf) 509 | 510 | def I2C_Write_Repeated(self, addrs, data): 511 | """ Writes a block of data with Repeated Start and Stop conditions on bus 512 | :param int addrs: 8-bit I2C slave address 513 | :param list data: list of int 514 | 515 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.6 516 | """ 517 | buf = [0x00, 0x92] 518 | self._i2c_write(addrs, data, buf) 519 | 520 | def I2C_Write_No_Stop(self, addrs, data): 521 | """ Writes a block of data with Start condition on bus 522 | :param int addrs: 8-bit I2C slave address 523 | :param list data: list of int 524 | 525 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.7 526 | """ 527 | buf = [0x00, 0x94] 528 | self._i2c_write(addrs, data, buf) 529 | 530 | def _i2c_write(self, addrs, data, buf): 531 | buf = buf + [0 for i in range(65 - len(buf))] 532 | buf[1 + 1] = (len(data) & 0x00FF) # Cancel current I2C/SMBus transfer (sub-command) 533 | buf[2 + 1] = (len(data) & 0xFF00) >> 8 # Set I2C/SMBus communication speed (sub-command) 534 | # The I2C/SMBus system clock divider that will be used to establish the communication speed 535 | buf[3 + 1] = 0xFF & (addrs << 1) 536 | for i in range(len(data)): 537 | # print ("{:d}: 0x{:02x}".format(i,data[i])) 538 | buf[4 + 1 + i] = data[i] # The I2C/SMBus system clock divider that will be used to establish the communication speed 539 | self.mcp2221a.write(buf) 540 | rbuf = self.mcp2221a.read(65) 541 | time.sleep(0.008) 542 | 543 | 544 | ####################################################################### 545 | # I2C Read 546 | ####################################################################### 547 | def I2C_Read(self, addrs, size): 548 | """ Reads a block of data with Start and Stop conditions on bus 549 | :param int addrs: 8-bit I2C slave address 550 | :param int size: size of read out in bytes 551 | 552 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.8 553 | """ 554 | buf = [0x00, 0x91] 555 | return self._i2c_read(addrs, size, buf) 556 | 557 | def I2C_Read_Repeated(self, addrs, size): 558 | """ Reads a block of data with Repeated Start and Stop conditions on bus 559 | :param int addrs: 8-bit I2C slave address 560 | :param int size: size of read out in bytes 561 | 562 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.9 563 | """ 564 | buf = [0x00, 0x93] 565 | return self._i2c_read(addrs, size, buf) 566 | 567 | def _i2c_read(self, addrs, size, buf): 568 | buf = buf + [0 for i in range(65 - len(buf))] 569 | 570 | buf[1 + 1] = (size & 0x00FF) # Read LEN 571 | buf[2 + 1] = (size & 0xFF00) >> 8 # Read LEN 572 | buf[3 + 1] = 0xFF & (addrs << 1) # addrs 573 | self.mcp2221a.write(buf) 574 | rbuf = self.mcp2221a.read(65) 575 | if (rbuf[1] != 0x00): 576 | # print("[0x91:0x{:02x},0x{:02x},0x{:02x}]".format(rbuf[1],rbuf[2],rbuf[3])) 577 | self.I2C_Cancel() 578 | self.I2C_Init() 579 | return -1 580 | # time.sleep(0.1) 581 | buf = [0x00, 0x40] 582 | buf = buf + [0 for i in range(65 - len(buf))] 583 | buf[1 + 1] = 0x00 584 | buf[2 + 1] = 0x00 585 | buf[3 + 1] = 0x00 586 | self.mcp2221a.write(buf) 587 | rbuf = self.mcp2221a.read(65) 588 | if (rbuf[1] != 0x00): 589 | # print("[0x40:0x{:02x},0x{:02x},0x{:02x}]".format(rbuf[1],rbuf[2],rbuf[3])) 590 | self.I2C_Cancel() 591 | self.I2C_Init() 592 | return -1 593 | if (rbuf[2] == 0x00 and rbuf[3] == 0x00): 594 | self.I2C_Cancel() 595 | self.I2C_Init() 596 | return rbuf[4] 597 | if (rbuf[2] == 0x55 and rbuf[3] == size): 598 | rdata = [0] * size 599 | for i in range(size): 600 | rdata[i] = rbuf[4 + i] 601 | return rdata 602 | 603 | 604 | ####################################################################### 605 | # reset 606 | ####################################################################### 607 | def Reset(self): 608 | print ("Reset") 609 | buf = [0x00, 0x70, 0xAB, 0xCD, 0xEF] 610 | buf = buf + [0 for i in range(65 - len(buf))] 611 | self.mcp2221a.write(buf) 612 | time.sleep(1) 613 | -------------------------------------------------------------------------------- /pypi/main/PyMCP2221A/PyMCP2221A.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | 6 | import hid 7 | #import hid 8 | # pip install hidapi 9 | # https://github.com/trezor/cython-hidapi 10 | import time 11 | 12 | 13 | class PyMCP2221A: 14 | def __init__(self,VID = 0x04D8,PID = 0x00DD,devnum = 0): 15 | self.mcp2221a = hid.device() 16 | self.mcp2221a.open_path(hid.enumerate(VID, PID)[devnum]["path"]) 17 | self.CLKDUTY_0 = 0x00 18 | self.CLKDUTY_25 = 0x08 19 | self.CLKDUTY_50 = 0x10 20 | self.CLKDUTY_75 = 0x18 21 | # self.CLKDIV_1 = 0x00 # 48MHz Dont work. 22 | self.CLKDIV_2 = 0x01 # 24MHz 23 | self.CLKDIV_4 = 0x02 # 12MHz 24 | self.CLKDIV_8 = 0x03 # 6MHz 25 | self.CLKDIV_16 = 0x04 # 3MHz 26 | self.CLKDIV_32 = 0x05 # 1.5MHz 27 | self.CLKDIV_64 = 0x06 # 750KHz 28 | self.CLKDIV_128 = 0x07 # 375KHz 29 | ####################################################################### 30 | # HID DeviceDriver Info 31 | ####################################################################### 32 | def DeviceDriverInfo(self): 33 | print("Manufacturer: %s" % self.mcp2221a.get_manufacturer_string()) 34 | print("Product: %s" % self.mcp2221a.get_product_string()) 35 | print("Serial No: %s" % self.mcp2221a.get_serial_number_string()) 36 | 37 | 38 | ####################################################################### 39 | # Command Structure 40 | ####################################################################### 41 | def Command_Structure(self, I2C_Cancel_Bit, I2C_Speed_SetUp_Bit, I2C_Speed_SetVal_Byte): 42 | I2C_Cancel_Bit = 0 43 | I2C_Speed_SetUp_Bit = 0 44 | I2C_Speed_SetVal_Byte = 0 45 | buf = [0x00, 0x10, 0x00, I2C_Cancel_Bit << 4, I2C_Speed_SetUp_Bit << 5, I2C_Speed_SetVal_Byte] 46 | buf = buf + [0 for i in range(65 - len(buf))] 47 | self.mcp2221a.write(buf) 48 | buf = self.mcp2221a.read(65) 49 | 50 | print (chr(buf[46])) 51 | print (chr(buf[47])) 52 | print (chr(buf[48])) 53 | print (chr(buf[49])) 54 | ####################################################################### 55 | # Read Flash Data 56 | ####################################################################### 57 | 58 | def Read_Flash_Data(self, Read_Deta_Setting_Byte): 59 | Read_Deta_Setting_Byte = 0x00 60 | # Read_Chip_Settings = 0x00 61 | # Read_GP_Settings = 0x01 62 | # Read_USB_Manufacturer_Settings = 0x02 63 | # Read_USB_Product_Settings = 0x03 64 | # Read_USB_SerialNum_Settings = 0x04 65 | # Read_Chip_Factory_Settings = 0x05 66 | buf = [0x00, 0xB0, Read_Deta_Setting_Byte] 67 | buf = buf + [0 for i in range(65 - len(buf))] 68 | # print ("Write") 69 | # print (buf) 70 | self.mcp2221a.write(buf) 71 | buf = self.mcp2221a.read(65) 72 | # print ("Read") 73 | # print (buf) 74 | ####################################################################### 75 | # Write Flash Data 76 | ####################################################################### 77 | 78 | def Write_Flash_Data(self, data): 79 | pass 80 | # Write_Deta_Setting_Byte = 0x00 81 | # Write_Chip_Settings = 0x00 82 | # Write_GP_Settings = 0x01 83 | # Write_USB_Manufacturer_Settings = 0x02 84 | # Write_USB_Product_Settings = 0x03 85 | # Write_USB_SerialNum_Settings = 0x04 86 | # buf = [0x00,0xB1,Write_Deta_Setting_Byte] 87 | # buf = buf + [0 for i in range(65-len(buf))] 88 | # !!!! Be careful when making changes !!!! 89 | # buf[6+1] = 0xD8 # VID (Lower) 90 | # buf[7+1] = 0x04 # VID (Higher) 91 | # buf[8+1] = 0xDD # PID (Lower) 92 | # buf[9+1] = 0x00 # PID (Higher) 93 | 94 | # print ("Write") 95 | # print (buf) 96 | # h.write(buf) 97 | # buf = h.read(65) 98 | # print ("Read") 99 | # print (buf) 100 | 101 | ####################################################################### 102 | # GPIO Init 103 | ####################################################################### 104 | def GPIO_Init(self): 105 | buf = [0x00, 0x61] 106 | buf = buf + [0 for i in range(65 - len(buf))] 107 | self.mcp2221a.write(buf) 108 | rbuf = self.mcp2221a.read(65) 109 | 110 | buf = [0x00, 0x60] 111 | buf = buf + [0 for i in range(65 - len(buf))] 112 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 113 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 114 | buf[4 + 1] = 0x00 # Set DAC output value 115 | buf[5 + 1] = 0x00 # ADC Voltage Reference 116 | # buf[6+1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 117 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 118 | # datasheet says this should be 1, but should actually be 0x80 119 | 120 | self.GPIO_0_BIT = (rbuf[22 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 121 | self.GPIO_0_DIR = (rbuf[22 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 122 | self.GPIO_0_MODE = rbuf[22 + 1] & 0x07 # GPIO MODE = 0x00 123 | self.GPIO_1_BIT = (rbuf[23 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 124 | self.GPIO_1_DIR = (rbuf[23 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 125 | self.GPIO_1_MODE = rbuf[23 + 1] & 0x07 # GPIO MODE = 0x00 126 | self.GPIO_2_BIT = (rbuf[24 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 127 | self.GPIO_2_DIR = (rbuf[24 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 128 | self.GPIO_2_MODE = rbuf[24 + 1] & 0x07 # GPIO MODE = 0x00 129 | self.GPIO_3_BIT = (rbuf[25 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 130 | self.GPIO_3_DIR = (rbuf[25 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 131 | self.GPIO_3_MODE = rbuf[25 + 1] & 0x07 # GPIO MODE = 0x00 132 | 133 | # for(i in range(64)): 134 | # buf[i] = rbuf[i] | buf[i] 135 | self.mcp2221a.write(buf) 136 | buf = self.mcp2221a.read(65) 137 | 138 | 139 | ####################################################################### 140 | # GPIO Write command 141 | ####################################################################### 142 | def GPIO_Write(self): 143 | buf = [0x00, 0x61] 144 | buf = buf + [0 for i in range(65 - len(buf))] 145 | self.mcp2221a.write(buf) 146 | rbuf = self.mcp2221a.read(65) 147 | 148 | buf = [0x00, 0x60] 149 | buf = buf + [0 for i in range(65 - len(buf))] 150 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 151 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 152 | # buf[4+1] = 0x00 # Set DAC output value 153 | # buf[5+1] = 0x00 # ADC Voltage Reference 154 | # buf[6+1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 155 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 156 | # datasheet says this should be 1, but should actually be 0x80 157 | 158 | buf[8 + 1] = self.GPIO_0_BIT << 4 | self.GPIO_0_DIR << 3 | self.GPIO_0_MODE # GP0 settings 159 | buf[9 + 1] = self.GPIO_1_BIT << 4 | self.GPIO_1_DIR << 3 | self.GPIO_1_MODE # GP0 settings 160 | buf[10 + 1] = self.GPIO_2_BIT << 4 | self.GPIO_2_DIR << 3 | self.GPIO_2_MODE # GP0 settings 161 | buf[11 + 1] = self.GPIO_3_BIT << 4 | self.GPIO_3_DIR << 3 | self.GPIO_3_MODE # GP0 settings 162 | # print (buf) 163 | # for(i in range(64)): 164 | # buf[i] = rbuf[i] | buf[i] 165 | self.mcp2221a.write(buf) 166 | self.mcp2221a.read(65) 167 | 168 | ####################################################################### 169 | # Read GPIO Data command 170 | ####################################################################### 171 | def GPIO_Read(self): 172 | buf = [0x00, 0x51] 173 | buf = buf + [0 for i in range(65 - len(buf))] 174 | self.mcp2221a.write(buf) 175 | buf = self.mcp2221a.read(65) 176 | self.GPIO_0_INPUT = buf[2] 177 | self.GPIO_0_DIR = buf[3] 178 | self.GPIO_1_INPUT = buf[4] 179 | self.GPIO_1_DIR = buf[5] 180 | self.GPIO_2_INPUT = buf[6] 181 | self.GPIO_2_DIR = buf[7] 182 | self.GPIO_3_INPUT = buf[8] 183 | self.GPIO_3_DIR = buf[9] 184 | 185 | ####################################################################### 186 | # GPIO Outpu/Input Data 187 | ####################################################################### 188 | def GPIO_0_Output(self, bit): 189 | self.GPIO_0_BIT = bit # 1:Hi 0:LOW 190 | self.GPIO_0_DIR = 0 # 0:OutPut 1:Input 191 | self.GPIO_0_MODE = 0 # 0:GPIO 192 | self.GPIO_Write() 193 | 194 | def GPIO_0_InputMode(self): 195 | self.GPIO_0_DIR = 1 # 0:OutPut 1:Input 196 | self.GPIO_Write() 197 | 198 | def GPIO_0_OutputMode(self): 199 | self.GPIO_0_DIR = 0 # 0:OutPut 1:Input 200 | self.GPIO_Write() 201 | 202 | def GPIO_0_Input(self): 203 | self.GPIO_Read() 204 | return self.GPIO_0_INPUT, self.GPIO_0_DIR 205 | 206 | def GPIO_1_Output(self, bit): 207 | self.GPIO_1_BIT = bit # 1:Hi 0:LOW 208 | self.GPIO_1_DIR = 0 # 0:OutPut 1:Input 209 | self.GPIO_1_MODE = 0 # 0:GPIO 210 | self.GPIO_Write() 211 | 212 | def GPIO_1_InputMode(self): 213 | self.GPIO_1_DIR = 1 # 0:OutPut 1:Input 214 | self.GPIO_Write() 215 | 216 | def GPIO_1_OutputMode(self): 217 | self.GPIO_1_DIR = 0 # 0:OutPut 1:Input 218 | self.GPIO_Write() 219 | 220 | def GPIO_1_Input(self): 221 | self.GPIO_Read() 222 | return self.GPIO_1_INPUT, self.GPIO_1_DIR 223 | 224 | def GPIO_2_Output(self, bit): 225 | self.GPIO_2_BIT = bit # 1:Hi 0:LOW 226 | self.GPIO_2_DIR = 0 # 0:OutPut 1:Input 227 | self.GPIO_2_MODE = 0 # 0:GPIO 228 | self.GPIO_Write() 229 | 230 | def GPIO_2_InputMode(self): 231 | self.GPIO_2_DIR = 1 # 0:OutPut 1:Input 232 | self.GPIO_Write() 233 | 234 | def GPIO_2_OutputMode(self): 235 | self.GPIO_2_DIR = 0 # 0:OutPut 1:Input 236 | self.GPIO_Write() 237 | 238 | def GPIO_2_Input(self): 239 | self.GPIO_Read() 240 | return self.GPIO_2_INPUT, self.GPIO_2_DIR 241 | 242 | def GPIO_3_Output(self, bit): 243 | self.GPIO_3_BIT = bit # 1:Hi 0:LOW 244 | self.GPIO_3_DIR = 0 # 0:OutPut 1:Input 245 | self.GPIO_3_MODE = 0 # 0:GPIO 246 | self.GPIO_Write() 247 | 248 | def GPIO_3_InputMode(self): 249 | self.GPIO_3_DIR = 1 # 0:OutPut 1:Input 250 | self.GPIO_Write() 251 | 252 | def GPIO_3_OutputMode(self): 253 | self.GPIO_3_DIR = 0 # 0:OutPut 1:Input 254 | self.GPIO_Write() 255 | 256 | def GPIO_3_Input(self): 257 | self.GPIO_Read() 258 | return self.GPIO_3_INPUT, self.GPIO_3_DIR 259 | 260 | 261 | ####################################################################### 262 | # Clock Out Value & Duty 263 | ####################################################################### 264 | def ClockOut(self, duty, value): 265 | buf = [0x00, 0x61] 266 | buf = buf + [0 for i in range(65 - len(buf))] 267 | self.mcp2221a.write(buf) 268 | rbuf = self.mcp2221a.read(65) 269 | 270 | buf = [0x00, 0x60] 271 | buf = buf + [0 for i in range(65 - len(buf))] 272 | buf[2 + 1] = 0x80 | duty | (0x07 & value) # Clock Output Divider value 273 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 274 | buf[4 + 1] = 0x00 # Set DAC output value 275 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 276 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 277 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 278 | # datasheet says this should be 1, but should actually be 0x80 279 | buf[8 + 1] = rbuf[22] # GP0 settings 280 | buf[9 + 1] = 0x01 # GP1 settings 281 | buf[10 + 1] = rbuf[24] # GP2 settings 282 | buf[11 + 1] = rbuf[25] # GP3 settings 283 | self.mcp2221a.write(buf) 284 | buf = self.mcp2221a.read(65) 285 | 286 | ####################################################################### 287 | # ADC 1 288 | ####################################################################### 289 | def ADC_1_Init(self): 290 | buf = [0x00, 0x61] 291 | buf = buf + [0 for i in range(65 - len(buf))] 292 | self.mcp2221a.write(buf) 293 | rbuf = self.mcp2221a.read(65) 294 | 295 | buf = [0x00, 0x60] 296 | buf = buf + [0 for i in range(65 - len(buf))] 297 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 298 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 299 | buf[4 + 1] = 0x00 # Set DAC output value 300 | buf[5 + 1] = 0x00 # ADC Voltage Reference 301 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 302 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 303 | # datasheet says this should be 1, but should actually be 0x80 304 | buf[8 + 1] = rbuf[22] # GP0 settings 305 | buf[9 + 1] = 0x02 # GP1 settings 306 | buf[10 + 1] = rbuf[24] # GP2 settings 307 | buf[11 + 1] = rbuf[25] # GP3 settings 308 | self.mcp2221a.write(buf) 309 | buf = self.mcp2221a.read(65) 310 | ####################################################################### 311 | # ADC 2 312 | ####################################################################### 313 | 314 | def ADC_2_Init(self): 315 | buf = [0x00, 0x61] 316 | buf = buf + [0 for i in range(65 - len(buf))] 317 | self.mcp2221a.write(buf) 318 | rbuf = self.mcp2221a.read(65) 319 | 320 | buf = [0x00, 0x60] 321 | buf = buf + [0 for i in range(65 - len(buf))] 322 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 323 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 324 | buf[4 + 1] = 0x00 # Set DAC output value 325 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 326 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 327 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 328 | # datasheet says this should be 1, but should actually be 0x80 329 | buf[8 + 1] = rbuf[22] # GP0 settings 330 | buf[9 + 1] = rbuf[23] # GP1 settings 331 | buf[10 + 1] = 0x02 # GP2 settings 332 | buf[11 + 1] = rbuf[25] # GP3 settings 333 | self.mcp2221a.write(buf) 334 | buf = self.mcp2221a.read(65) 335 | ####################################################################### 336 | # ADC 3 337 | ####################################################################### 338 | 339 | def ADC_3_Init(self): 340 | buf = [0x00, 0x61] 341 | buf = buf + [0 for i in range(65 - len(buf))] 342 | self.mcp2221a.write(buf) 343 | rbuf = self.mcp2221a.read(65) 344 | 345 | buf = [0x00, 0x60] 346 | buf = buf + [0 for i in range(65 - len(buf))] 347 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 348 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 349 | buf[4 + 1] = 0x00 # Set DAC output value 350 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 351 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 352 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 353 | # datasheet says this should be 1, but should actually be 0x80 354 | buf[8 + 1] = rbuf[22] # GP0 settings 355 | buf[9 + 1] = rbuf[23] # GP1 settings 356 | buf[10 + 1] = rbuf[24] # GP2 settings 357 | buf[11 + 1] = 0x02 # GP3 settings 358 | self.mcp2221a.write(buf) 359 | buf = self.mcp2221a.read(65) 360 | ####################################################################### 361 | # ADC Deta Get 362 | ####################################################################### 363 | 364 | def ADC_DataRead(self): 365 | buf = [0x00, 0x10] 366 | buf = buf + [0 for i in range(65 - len(buf))] 367 | self.mcp2221a.write(buf) 368 | buf = self.mcp2221a.read(65) 369 | # for i in range(len(buf)): 370 | # print ("[%d]: 0x{:02x}".format(buf[i]) % (i)) 371 | self.ADC_1_data = buf[50] | (buf[51] << 8) # ADC Data (16-bit) values 372 | self.ADC_2_data = buf[52] | (buf[53] << 8) # ADC Data (16-bit) values 373 | self.ADC_3_data = buf[54] | (buf[55] << 8) # ADC Data (16-bit) values 374 | 375 | ####################################################################### 376 | # DAC 1 377 | ####################################################################### 378 | def DAC_1_Init(self): 379 | buf = [0x00, 0x61] 380 | buf = buf + [0 for i in range(65 - len(buf))] 381 | self.mcp2221a.write(buf) 382 | rbuf = self.mcp2221a.read(65) 383 | 384 | buf = [0x00, 0x60] 385 | buf = buf + [0 for i in range(65 - len(buf))] 386 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 387 | buf[3 + 1] = 0x00 # DAC Voltage Reference 388 | buf[4 + 1] = 0x00 # Set DAC output value 389 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 390 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 391 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 392 | # datasheet says this should be 1, but should actually be 0x80 393 | buf[8 + 1] = rbuf[22] # GP0 settings 394 | buf[9 + 1] = rbuf[23] # GP1 settings 395 | buf[10 + 1] = 0x03 # GP2 settings 396 | buf[11 + 1] = rbuf[25] # GP3 settings 397 | self.mcp2221a.write(buf) 398 | buf = self.mcp2221a.read(65) 399 | ####################################################################### 400 | # DAC 2 401 | ####################################################################### 402 | 403 | def DAC_2_Init(self): 404 | buf = [0x00, 0x61] 405 | buf = buf + [0 for i in range(65 - len(buf))] 406 | self.mcp2221a.write(buf) 407 | rbuf = self.mcp2221a.read(65) 408 | 409 | buf = [0x00, 0x60] 410 | buf = buf + [0 for i in range(65 - len(buf))] 411 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 412 | buf[3 + 1] = 0x00 # DAC Voltage Reference 413 | buf[4 + 1] = 0x00 # Set DAC output value 414 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 415 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 416 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 417 | # datasheet says this should be 1, but should actually be 0x80 418 | buf[8 + 1] = rbuf[22] # GP0 settings 419 | buf[9 + 1] = rbuf[23] # GP1 settings 420 | buf[10 + 1] = rbuf[24] # GP2 settings 421 | buf[11 + 1] = 0x03 # GP3 settings 422 | self.mcp2221a.write(buf) 423 | buf = self.mcp2221a.read(65) 424 | ####################################################################### 425 | # DAC Output 426 | ####################################################################### 427 | 428 | def DAC_Datawrite(self, value): 429 | buf = [0x00, 0x61] 430 | buf = buf + [0 for i in range(65 - len(buf))] 431 | self.mcp2221a.write(buf) 432 | rbuf = self.mcp2221a.read(65) 433 | 434 | buf = [0x00, 0x60] 435 | buf = buf + [0 for i in range(65 - len(buf))] 436 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 437 | buf[3 + 1] = 0x00 # DAC Voltage Reference 438 | buf[4 + 1] = 0x80 | (0x0F & value) # Set DAC output value 439 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 440 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 441 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 442 | # datasheet says this should be 1, but should actually be 0x80 443 | buf[8 + 1] = rbuf[22] # GP0 settings 444 | buf[9 + 1] = rbuf[23] # GP1 settings 445 | buf[10 + 1] = rbuf[24] # GP2 settings 446 | buf[11 + 1] = rbuf[25] # GP3 settings 447 | self.mcp2221a.write(buf) 448 | buf = self.mcp2221a.read(65) 449 | 450 | 451 | ####################################################################### 452 | # I2C Init 453 | ####################################################################### 454 | def I2C_Init(self, speed=100000): # speed = 100000 455 | 456 | buf = [0x00, 0x10] 457 | buf = buf + [0 for i in range(65 - len(buf))] 458 | buf[2 + 1] = 0x00 # Cancel current I2C/SMBus transfer (sub-command) 459 | buf[3 + 1] = 0x20 # Set I2C/SMBus communication speed (sub-command) 460 | # The I2C/SMBus system clock divider that will be used to establish the communication speed 461 | buf[4 + 1] = int((12000000 / speed) - 3) 462 | self.mcp2221a.write(buf) 463 | rbuf = self.mcp2221a.read(65) 464 | # print("Init") 465 | if(rbuf[22] == 0): 466 | print("SCL is low.") 467 | exit() 468 | return -1 469 | if(rbuf[23] == 0): 470 | print("SDA is low.") 471 | exit() 472 | return -1 473 | 474 | # time.sleep(0.001) 475 | 476 | ####################################################################### 477 | # I2C State Check 478 | ####################################################################### 479 | def I2C_State_Check(self): 480 | buf = [0x00, 0x10] 481 | buf = buf + [0 for i in range(65 - len(buf))] 482 | self.mcp2221a.write(buf) 483 | rbuf = self.mcp2221a.read(65) 484 | return rbuf[8] 485 | ####################################################################### 486 | # I2C Cancel 487 | ####################################################################### 488 | 489 | def I2C_Cancel(self): 490 | buf = [0x00, 0x10] 491 | buf = buf + [0 for i in range(65 - len(buf))] 492 | buf[2 + 1] = 0x10 # Cancel current I2C/SMBus transfer (sub-command) 493 | self.mcp2221a.write(buf) 494 | self.mcp2221a.read(65) 495 | # time.sleep(0.1) 496 | 497 | ####################################################################### 498 | # I2C Write 499 | ####################################################################### 500 | def I2C_Write(self, addrs, data): 501 | """ Writes a block of data with Start and Stop c condition on bus 502 | :param int addrs: 7-bit I2C slave address 503 | :param list data: list of int 504 | 505 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.5 506 | """ 507 | buf = [0x00, 0x90] 508 | self._i2c_write(addrs, data, buf) 509 | 510 | def I2C_Write_Repeated(self, addrs, data): 511 | """ Writes a block of data with Repeated Start and Stop conditions on bus 512 | :param int addrs: 7-bit I2C slave address 513 | :param list data: list of int 514 | 515 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.6 516 | """ 517 | buf = [0x00, 0x92] 518 | self._i2c_write(addrs, data, buf) 519 | 520 | def I2C_Write_No_Stop(self, addrs, data): 521 | """ Writes a block of data with Start condition on bus 522 | :param int addrs: 7-bit I2C slave address 523 | :param list data: list of int 524 | 525 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.7 526 | """ 527 | buf = [0x00, 0x94] 528 | self._i2c_write(addrs, data, buf) 529 | 530 | def _i2c_write(self, addrs, data, buf): 531 | buf = buf + [0 for i in range(65 - len(buf))] 532 | buf[1 + 1] = (len(data) & 0x00FF) # Cancel current I2C/SMBus transfer (sub-command) 533 | buf[2 + 1] = (len(data) & 0xFF00) >> 8 # Set I2C/SMBus communication speed (sub-command) 534 | # The I2C/SMBus system clock divider that will be used to establish the communication speed 535 | buf[3 + 1] = 0xFF & (addrs << 1) 536 | for i in range(len(data)): 537 | # print ("{:d}: 0x{:02x}".format(i,data[i])) 538 | buf[4 + 1 + i] = data[i] # The I2C/SMBus system clock divider that will be used to establish the communication speed 539 | self.mcp2221a.write(buf) 540 | rbuf = self.mcp2221a.read(65) 541 | time.sleep(0.008) 542 | 543 | 544 | ####################################################################### 545 | # I2C Read 546 | ####################################################################### 547 | def I2C_Read(self, addrs, size): 548 | """ Reads a block of data with Start and Stop conditions on bus 549 | :param int addrs: 7-bit I2C slave address 550 | :param int size: size of read out in bytes 551 | 552 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.8 553 | """ 554 | buf = [0x00, 0x91] 555 | return self._i2c_read(addrs, size, buf) 556 | 557 | def I2C_Read_Repeated(self, addrs, size): 558 | """ Reads a block of data with Repeated Start and Stop conditions on bus 559 | :param int addrs: 7-bit I2C slave address 560 | :param int size: size of read out in bytes 561 | 562 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.9 563 | """ 564 | buf = [0x00, 0x93] 565 | return self._i2c_read(addrs, size, buf) 566 | 567 | def _i2c_read(self, addrs, size, buf): 568 | buf = buf + [0 for i in range(65 - len(buf))] 569 | 570 | buf[1 + 1] = (size & 0x00FF) # Read LEN 571 | buf[2 + 1] = (size & 0xFF00) >> 8 # Read LEN 572 | buf[3 + 1] = 0xFF & (addrs << 1) # addrs 573 | self.mcp2221a.write(buf) 574 | rbuf = self.mcp2221a.read(65) 575 | if (rbuf[1] != 0x00): 576 | # print("[0x91:0x{:02x},0x{:02x},0x{:02x}]".format(rbuf[1],rbuf[2],rbuf[3])) 577 | self.I2C_Cancel() 578 | self.I2C_Init() 579 | return -1 580 | # time.sleep(0.1) 581 | buf = [0x00, 0x40] 582 | buf = buf + [0 for i in range(65 - len(buf))] 583 | buf[1 + 1] = 0x00 584 | buf[2 + 1] = 0x00 585 | buf[3 + 1] = 0x00 586 | self.mcp2221a.write(buf) 587 | rbuf = self.mcp2221a.read(65) 588 | if (rbuf[1] != 0x00): 589 | # print("[0x40:0x{:02x},0x{:02x},0x{:02x}]".format(rbuf[1],rbuf[2],rbuf[3])) 590 | self.I2C_Cancel() 591 | self.I2C_Init() 592 | return -1 593 | if (rbuf[2] == 0x00 and rbuf[3] == 0x00): 594 | self.I2C_Cancel() 595 | self.I2C_Init() 596 | return rbuf[4] 597 | if (rbuf[2] == 0x55 and rbuf[3] == size): 598 | rdata = [0] * size 599 | for i in range(size): 600 | rdata[i] = rbuf[4 + i] 601 | return rdata 602 | 603 | 604 | ####################################################################### 605 | # reset 606 | ####################################################################### 607 | def Reset(self): 608 | print ("Reset") 609 | buf = [0x00, 0x70, 0xAB, 0xCD, 0xEF] 610 | buf = buf + [0 for i in range(65 - len(buf))] 611 | self.mcp2221a.write(buf) 612 | time.sleep(1) 613 | -------------------------------------------------------------------------------- /PyMCP2221A/PyMCP2221A.py: -------------------------------------------------------------------------------- 1 | ############################################################# 2 | # MIT License # 3 | # Copyright (c) 2017 Yuta KItagami # 4 | ############################################################# 5 | 6 | import hid 7 | # import hid 8 | # pip install hidapi 9 | # https://github.com/trezor/cython-hidapi 10 | import time 11 | import os 12 | 13 | PACKET_SIZE = 65 14 | DIR_OUTPUT = 0 15 | DIR_INPUT = 1 16 | 17 | 18 | class PyMCP2221A: 19 | def __init__(self, VID=0x04D8, PID=0x00DD, devnum=0): 20 | self.mcp2221a = hid.device() 21 | self.mcp2221a.open_path(hid.enumerate(VID, PID)[devnum]["path"]) 22 | self.CLKDUTY_0 = 0x00 23 | self.CLKDUTY_25 = 0x08 24 | self.CLKDUTY_50 = 0x10 25 | self.CLKDUTY_75 = 0x18 26 | # self.CLKDIV_1 = 0x00 # 48MHz Dont work. 27 | self.CLKDIV_2 = 0x01 # 24MHz 28 | self.CLKDIV_4 = 0x02 # 12MHz 29 | self.CLKDIV_8 = 0x03 # 6MHz 30 | self.CLKDIV_16 = 0x04 # 3MHz 31 | self.CLKDIV_32 = 0x05 # 1.5MHz 32 | self.CLKDIV_64 = 0x06 # 750KHz 33 | self.CLKDIV_128 = 0x07 # 375KHz 34 | 35 | def compile_packet(self, buf): 36 | """ 37 | :param list buf: 38 | """ 39 | assert len(buf) <= PACKET_SIZE 40 | 41 | buf = buf + [0 for i in range(PACKET_SIZE - len(buf))] 42 | return buf 43 | 44 | ####################################################################### 45 | # HID DeviceDriver Info 46 | ####################################################################### 47 | def DeviceDriverInfo(self): 48 | print("Manufacturer: %s" % self.mcp2221a.get_manufacturer_string()) 49 | print("Product: %s" % self.mcp2221a.get_product_string()) 50 | print("Serial No: %s" % self.mcp2221a.get_serial_number_string()) 51 | 52 | ####################################################################### 53 | # Command Structure 54 | ####################################################################### 55 | def Command_Structure(self, I2C_Cancel_Bit, I2C_Speed_SetUp_Bit, I2C_Speed_SetVal_Byte): 56 | I2C_Cancel_Bit = 0 57 | I2C_Speed_SetUp_Bit = 0 58 | I2C_Speed_SetVal_Byte = 0 59 | buf = self.compile_packet([0x00, 0x10, 0x00, 60 | I2C_Cancel_Bit << 4, 61 | I2C_Speed_SetUp_Bit << 5, 62 | I2C_Speed_SetVal_Byte]) 63 | 64 | self.mcp2221a.write(buf) 65 | buf = self.mcp2221a.read(PACKET_SIZE) 66 | 67 | print(chr(buf[46])) 68 | print(chr(buf[47])) 69 | print(chr(buf[48])) 70 | print(chr(buf[49])) 71 | 72 | ####################################################################### 73 | # Read Flash Data 74 | ####################################################################### 75 | 76 | def Read_Flash_Data(self, Read_Deta_Setting_Byte): 77 | Read_Deta_Setting_Byte = 0x00 78 | # Read_Chip_Settings = 0x00 79 | # Read_GP_Settings = 0x01 80 | # Read_USB_Manufacturer_Settings = 0x02 81 | # Read_USB_Product_Settings = 0x03 82 | # Read_USB_SerialNum_Settings = 0x04 83 | # Read_Chip_Factory_Settings = 0x05 84 | 85 | buf = self.compile_packet([0x00, 0xB0, Read_Deta_Setting_Byte]) 86 | # print ("Write") 87 | # print (buf) 88 | self.mcp2221a.write(buf) 89 | 90 | buf = self.mcp2221a.read(PACKET_SIZE) 91 | # print ("Read") 92 | # print (buf) 93 | 94 | ####################################################################### 95 | # Write Flash Data 96 | ####################################################################### 97 | 98 | def Write_Flash_Data(self, data): 99 | pass 100 | # Write_Deta_Setting_Byte = 0x00 101 | # Write_Chip_Settings = 0x00 102 | # Write_GP_Settings = 0x01 103 | # Write_USB_Manufacturer_Settings = 0x02 104 | # Write_USB_Product_Settings = 0x03 105 | # Write_USB_SerialNum_Settings = 0x04 106 | # buf = [0x00,0xB1,Write_Deta_Setting_Byte] 107 | # buf = buf + [0 for i in range(PACKET_SIZE-len(buf))] 108 | # !!!! Be careful when making changes !!!! 109 | # buf[6+1] = 0xD8 # VID (Lower) 110 | # buf[7+1] = 0x04 # VID (Higher) 111 | # buf[8+1] = 0xDD # PID (Lower) 112 | # buf[9+1] = 0x00 # PID (Higher) 113 | 114 | # print ("Write") 115 | # print (buf) 116 | # h.write(buf) 117 | # buf = h.read(PACKET_SIZE) 118 | # print ("Read") 119 | # print (buf) 120 | 121 | ####################################################################### 122 | # GPIO Init 123 | ####################################################################### 124 | def GPIO_Init(self): 125 | buf = self.compile_packet([0x00, 0x61]) 126 | self.mcp2221a.write(buf) 127 | 128 | rbuf = self.mcp2221a.read(PACKET_SIZE) 129 | 130 | buf = self.compile_packet([0x00, 0x60]) 131 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 132 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 133 | buf[4 + 1] = 0x00 # Set DAC output value 134 | buf[5 + 1] = 0x00 # ADC Voltage Reference 135 | # buf[6+1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 136 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 137 | # datasheet says this should be 1, but should actually be 0x80 138 | 139 | self.GPIO_0_BIT = (rbuf[22 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 140 | self.GPIO_0_DIR = (rbuf[22 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 141 | self.GPIO_0_MODE = rbuf[22 + 1] & 0x07 # GPIO MODE = 0x00 142 | self.GPIO_1_BIT = (rbuf[23 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 143 | self.GPIO_1_DIR = (rbuf[23 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 144 | self.GPIO_1_MODE = rbuf[23 + 1] & 0x07 # GPIO MODE = 0x00 145 | self.GPIO_2_BIT = (rbuf[24 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 146 | self.GPIO_2_DIR = (rbuf[24 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 147 | self.GPIO_2_MODE = rbuf[24 + 1] & 0x07 # GPIO MODE = 0x00 148 | self.GPIO_3_BIT = (rbuf[25 + 1] >> 4) & 0x01 # 1:Hi 0:LOW 149 | self.GPIO_3_DIR = (rbuf[25 + 1] >> 3) & 0x01 # 0:OutPut 1:Input 150 | self.GPIO_3_MODE = rbuf[25 + 1] & 0x07 # GPIO MODE = 0x00 151 | 152 | # for(i in range(64)): 153 | # buf[i] = rbuf[i] | buf[i] 154 | self.mcp2221a.write(buf) 155 | buf = self.mcp2221a.read(PACKET_SIZE) 156 | 157 | ####################################################################### 158 | # GPIO Set Direction and Set Value commands 159 | ####################################################################### 160 | def GPIO_SetDirection(self, pin, direction): 161 | 162 | buf = self.compile_packet([0x00, 0x50]) 163 | offset = (pin + 1) * 4 164 | buf[offset + 1] = 0x01 # set pin direction 165 | buf[offset + 1 + 1] = direction # to this 166 | self.mcp2221a.write(buf) 167 | 168 | rbuf = self.mcp2221a.read(PACKET_SIZE) 169 | if rbuf[1] != 0x00: 170 | raise RuntimeError("GPIO_SetDirection Failed") 171 | 172 | def GPIO_SetValue(self, pin, value): 173 | 174 | buf = self.compile_packet([0x00, 0x50]) 175 | offset = ((pin + 1) * 4) - 1 176 | buf[offset - 1 + 1] = 0x01 # set pin value 177 | buf[offset + 1] = value # to this 178 | self.mcp2221a.write(buf) 179 | 180 | rbuf = self.mcp2221a.read(PACKET_SIZE) 181 | if rbuf[1] != 0x00: 182 | raise RuntimeError("GPIO_SetValue Failed") 183 | 184 | ####################################################################### 185 | # Read GPIO Data command 186 | ####################################################################### 187 | def GPIO_Read(self): 188 | 189 | buf = self.compile_packet([0x00, 0x51]) 190 | self.mcp2221a.write(buf) 191 | 192 | buf = self.mcp2221a.read(PACKET_SIZE) 193 | self.GPIO_0_INPUT = buf[2] 194 | self.GPIO_0_DIR = buf[3] 195 | self.GPIO_1_INPUT = buf[4] 196 | self.GPIO_1_DIR = buf[5] 197 | self.GPIO_2_INPUT = buf[6] 198 | self.GPIO_2_DIR = buf[7] 199 | self.GPIO_3_INPUT = buf[8] 200 | self.GPIO_3_DIR = buf[9] 201 | return buf 202 | 203 | # Return the GPIO value as an integer instead of tuple 204 | def GPIO_GetValue(self, pin): 205 | rbuf = self.GPIO_Read() 206 | offset = (pin + 1) * 2 207 | if rbuf[offset] == 0xEE: 208 | raise RuntimeError("GPIO_GetValue Failed, pin is not set for GPIO operation") 209 | return rbuf[offset] 210 | 211 | ####################################################################### 212 | # GPIO Outpu/Input Data 213 | ####################################################################### 214 | def GPIO_0_Output(self, bit): 215 | self.GPIO_0_BIT = bit # 1:Hi 0:LOW 216 | self.GPIO_0_OutputMode() 217 | self.GPIO_SetValue(pin=0, value=self.GPIO_0_BIT) 218 | 219 | def GPIO_0_InputMode(self): 220 | self.GPIO_0_DIR = DIR_INPUT # 0:OutPut 1:Input 221 | self.GPIO_SetDirection(pin=0, direction=self.GPIO_0_DIR) 222 | 223 | def GPIO_0_OutputMode(self): 224 | self.GPIO_0_DIR = DIR_OUTPUT # 0:OutPut 1:Input 225 | self.GPIO_SetDirection(pin=0, direction=self.GPIO_0_DIR) 226 | 227 | def GPIO_0_Input(self): 228 | self.GPIO_Read() 229 | return self.GPIO_0_INPUT, self.GPIO_0_DIR 230 | 231 | def GPIO_1_Output(self, bit): 232 | self.GPIO_1_BIT = bit # 1:Hi 0:LOW 233 | self.GPIO_1_OutputMode() 234 | self.GPIO_SetValue(pin=1, value=self.GPIO_1_BIT) 235 | 236 | def GPIO_1_InputMode(self): 237 | self.GPIO_1_DIR = DIR_INPUT # 0:OutPut 1:Input 238 | self.GPIO_SetDirection(pin=1, direction=self.GPIO_1_DIR) 239 | 240 | def GPIO_1_OutputMode(self): 241 | self.GPIO_1_DIR = DIR_OUTPUT # 0:OutPut 1:Input 242 | self.GPIO_SetDirection(pin=1, direction=self.GPIO_1_DIR) 243 | 244 | def GPIO_1_Input(self): 245 | self.GPIO_Read() 246 | return self.GPIO_1_INPUT, self.GPIO_1_DIR 247 | 248 | def GPIO_2_Output(self, bit): 249 | self.GPIO_2_BIT = bit # 1:Hi 0:LOW 250 | self.GPIO_2_OutputMode() 251 | self.GPIO_SetValue(pin=2, value=self.GPIO_2_BIT) 252 | 253 | def GPIO_2_InputMode(self): 254 | self.GPIO_2_DIR = DIR_INPUT # 0:OutPut 1:Input 255 | self.GPIO_SetDirection(pin=2, direction=self.GPIO_2_DIR) 256 | 257 | def GPIO_2_OutputMode(self): 258 | self.GPIO_2_DIR = DIR_OUTPUT # 0:OutPut 1:Input 259 | self.GPIO_SetDirection(pin=2, direction=self.GPIO_2_DIR) 260 | 261 | def GPIO_2_Input(self): 262 | self.GPIO_Read() 263 | return self.GPIO_2_INPUT, self.GPIO_2_DIR 264 | 265 | def GPIO_3_Output(self, bit): 266 | self.GPIO_3_BIT = bit # 1:Hi 0:LOW 267 | self.GPIO_3_OutputMode() 268 | self.GPIO_SetValue(pin=3, value=self.GPIO_3_BIT) 269 | 270 | def GPIO_3_InputMode(self): 271 | self.GPIO_3_DIR = DIR_INPUT # 0:OutPut 1:Input 272 | self.GPIO_SetDirection(pin=3, direction=self.GPIO_3_DIR) 273 | 274 | def GPIO_3_OutputMode(self): 275 | self.GPIO_3_DIR = DIR_OUTPUT # 0:OutPut 1:Input 276 | self.GPIO_SetDirection(pin=3, direction=self.GPIO_3_DIR) 277 | 278 | def GPIO_3_Input(self): 279 | self.GPIO_Read() 280 | return self.GPIO_3_INPUT, self.GPIO_3_DIR 281 | 282 | ####################################################################### 283 | # Clock Out Value & Duty 284 | ####################################################################### 285 | def ClockOut(self, duty, value): 286 | """ 287 | :param int duty: Bit 4-3: Duty cycle 288 | 00 | 0% duty cycle 289 | 01 | 25% duty cycle 290 | 10 | 50% duty cycle 291 | 11 | 75% duty cycle 292 | :param int value: Bit 2-0: Clock divider value 293 | """ 294 | buf = self.compile_packet([0x00, 0x61]) # Get SRAM Settings 295 | 296 | self.mcp2221a.write(buf) 297 | rbuf = self.mcp2221a.read(PACKET_SIZE) 298 | 299 | buf = self.compile_packet([0x00, 0x60]) # Set SRAM Settings 300 | buf[2 + 1] = 0x80 | duty | (0x07 & value) # Clock Output Divider value 301 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 302 | buf[4 + 1] = 0x00 # Set DAC output value 303 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 304 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 305 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 306 | # datasheet says this should be 1, but should actually be 0x80 307 | buf[8 + 1] = rbuf[22] # GP0 settings 308 | buf[9 + 1] = 0x01 # GP1 settings - 001 Dedicated function operation (Clock Output) 309 | buf[10 + 1] = rbuf[24] # GP2 settings 310 | buf[11 + 1] = rbuf[25] # GP3 settings 311 | self.mcp2221a.write(buf) 312 | buf = self.mcp2221a.read(PACKET_SIZE) 313 | 314 | ####################################################################### 315 | # ADC 1 316 | ####################################################################### 317 | def ADC_1_Init(self): 318 | buf = self.compile_packet([0x00, 0x61]) 319 | self.mcp2221a.write(buf) 320 | 321 | rbuf = self.mcp2221a.read(PACKET_SIZE) 322 | 323 | buf = self.compile_packet([0x00, 0x60]) 324 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 325 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 326 | buf[4 + 1] = 0x00 # Set DAC output value 327 | buf[5 + 1] = 0x00 # ADC Voltage Reference 328 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 329 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 330 | # datasheet says this should be 1, but should actually be 0x80 331 | buf[8 + 1] = rbuf[22] # GP0 settings 332 | buf[9 + 1] = 0x02 # GP1 settings 333 | buf[10 + 1] = rbuf[24] # GP2 settings 334 | buf[11 + 1] = rbuf[25] # GP3 settings 335 | self.mcp2221a.write(buf) 336 | buf = self.mcp2221a.read(PACKET_SIZE) 337 | 338 | ####################################################################### 339 | # ADC 2 340 | ####################################################################### 341 | 342 | def ADC_2_Init(self): 343 | buf = self.compile_packet([0x00, 0x61]) 344 | self.mcp2221a.write(buf) 345 | 346 | rbuf = self.mcp2221a.read(PACKET_SIZE) 347 | 348 | buf = self.compile_packet([0x00, 0x60]) 349 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 350 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 351 | buf[4 + 1] = 0x00 # Set DAC output value 352 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 353 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 354 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 355 | # datasheet says this should be 1, but should actually be 0x80 356 | buf[8 + 1] = rbuf[22] # GP0 settings 357 | buf[9 + 1] = rbuf[23] # GP1 settings 358 | buf[10 + 1] = 0x02 # GP2 settings 359 | buf[11 + 1] = rbuf[25] # GP3 settings 360 | self.mcp2221a.write(buf) 361 | buf = self.mcp2221a.read(PACKET_SIZE) 362 | 363 | ####################################################################### 364 | # ADC 3 365 | ####################################################################### 366 | 367 | def ADC_3_Init(self): 368 | buf = self.compile_packet([0x00, 0x61]) 369 | 370 | self.mcp2221a.write(buf) 371 | rbuf = self.mcp2221a.read(PACKET_SIZE) 372 | 373 | buf = self.compile_packet([0x00, 0x60]) 374 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 375 | buf[3 + 1] = rbuf[6] # DAC Voltage Reference 376 | buf[4 + 1] = 0x00 # Set DAC output value 377 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 378 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 379 | buf[7 + 1] = 0x80 # Alter GPIO configuration: alters the current GP designation 380 | # datasheet says this should be 1, but should actually be 0x80 381 | buf[8 + 1] = rbuf[22] # GP0 settings 382 | buf[9 + 1] = rbuf[23] # GP1 settings 383 | buf[10 + 1] = rbuf[24] # GP2 settings 384 | buf[11 + 1] = 0x02 # GP3 settings 385 | self.mcp2221a.write(buf) 386 | buf = self.mcp2221a.read(PACKET_SIZE) 387 | 388 | ####################################################################### 389 | # ADC Deta Get 390 | ####################################################################### 391 | 392 | def ADC_DataRead(self): 393 | buf = self.compile_packet([0x00, 0x10]) 394 | self.mcp2221a.write(buf) 395 | 396 | buf = self.mcp2221a.read(PACKET_SIZE) 397 | # for i in range(len(buf)): 398 | # print ("[%d]: 0x{:02x}".format(buf[i]) % (i)) 399 | self.ADC_1_data = buf[50] | (buf[51] << 8) # ADC Data (16-bit) values 400 | self.ADC_2_data = buf[52] | (buf[53] << 8) # ADC Data (16-bit) values 401 | self.ADC_3_data = buf[54] | (buf[55] << 8) # ADC Data (16-bit) values 402 | 403 | ####################################################################### 404 | # DAC 1 405 | ####################################################################### 406 | def DAC_1_Init(self): 407 | buf = self.compile_packet([0x00, 0x61]) 408 | self.mcp2221a.write(buf) 409 | 410 | rbuf = self.mcp2221a.read(PACKET_SIZE) 411 | 412 | buf = self.compile_packet([0x00, 0x60]) 413 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 414 | buf[3 + 1] = 0x00 # DAC Voltage Reference 415 | buf[4 + 1] = 0x00 # Set DAC output value 416 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 417 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 418 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 419 | # datasheet says this should be 1, but should actually be 0x80 420 | buf[8 + 1] = rbuf[22] # GP0 settings 421 | buf[9 + 1] = rbuf[23] # GP1 settings 422 | buf[10 + 1] = 0x03 # GP2 settings 423 | buf[11 + 1] = rbuf[25] # GP3 settings 424 | self.mcp2221a.write(buf) 425 | buf = self.mcp2221a.read(PACKET_SIZE) 426 | 427 | ####################################################################### 428 | # DAC 2 429 | ####################################################################### 430 | 431 | def DAC_2_Init(self): 432 | buf = self.compile_packet([0x00, 0x61]) 433 | self.mcp2221a.write(buf) 434 | 435 | rbuf = self.mcp2221a.read(PACKET_SIZE) 436 | 437 | buf = self.compile_packet([0x00, 0x60]) 438 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 439 | buf[3 + 1] = 0x00 # DAC Voltage Reference 440 | buf[4 + 1] = 0x00 # Set DAC output value 441 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 442 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 443 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 444 | # datasheet says this should be 1, but should actually be 0x80 445 | buf[8 + 1] = rbuf[22] # GP0 settings 446 | buf[9 + 1] = rbuf[23] # GP1 settings 447 | buf[10 + 1] = rbuf[24] # GP2 settings 448 | buf[11 + 1] = 0x03 # GP3 settings 449 | self.mcp2221a.write(buf) 450 | buf = self.mcp2221a.read(PACKET_SIZE) 451 | 452 | ####################################################################### 453 | # DAC Output 454 | ####################################################################### 455 | 456 | def DAC_Datawrite(self, value): 457 | buf = self.compile_packet([0x00, 0x61]) 458 | self.mcp2221a.write(buf) 459 | 460 | rbuf = self.mcp2221a.read(PACKET_SIZE) 461 | 462 | buf = self.compile_packet([0x00, 0x60]) 463 | buf[2 + 1] = rbuf[5] # Clock Output Divider value 464 | buf[3 + 1] = 0x00 # DAC Voltage Reference 465 | buf[4 + 1] = 0x80 | (0x1F & value) # Set DAC output value 466 | buf[5 + 1] = rbuf[7] # ADC Voltage Reference 467 | buf[6 + 1] = 0x00 # Setup the interrupt detection mechanism and clear the detection flag 468 | buf[7 + 1] = 0xFF # Alter GPIO configuration: alters the current GP designation 469 | # datasheet says this should be 1, but should actually be 0x80 470 | buf[8 + 1] = rbuf[22] # GP0 settings 471 | buf[9 + 1] = rbuf[23] # GP1 settings 472 | buf[10 + 1] = rbuf[24] # GP2 settings 473 | buf[11 + 1] = rbuf[25] # GP3 settings 474 | self.mcp2221a.write(buf) 475 | buf = self.mcp2221a.read(PACKET_SIZE) 476 | 477 | ####################################################################### 478 | # I2C Init 479 | ####################################################################### 480 | def I2C_Init(self, speed=100000): # speed = 100000 481 | self.MCP2221_I2C_SLEEP = float(os.environ.get("MCP2221_I2C_SLEEP", 0)) 482 | 483 | buf = self.compile_packet([0x00, 0x10]) 484 | buf[2 + 1] = 0x00 # Cancel current I2C/SMBus transfer (sub-command) 485 | buf[3 + 1] = 0x20 # Set I2C/SMBus communication speed (sub-command) 486 | # The I2C/SMBus system clock divider that will be used to establish the communication speed 487 | buf[4 + 1] = int((12000000 / speed) - 3) 488 | self.mcp2221a.write(buf) 489 | 490 | rbuf = self.mcp2221a.read(PACKET_SIZE) 491 | # print("Init") 492 | if (rbuf[22] == 0): 493 | raise RuntimeError("SCL is low.") 494 | if (rbuf[23] == 0): 495 | raise RuntimeError("SDA is low.") 496 | 497 | # time.sleep(0.001) 498 | 499 | ####################################################################### 500 | # I2C State Check 501 | ####################################################################### 502 | def I2C_State_Check(self): 503 | buf = self.compile_packet([0x00, 0x10]) 504 | self.mcp2221a.write(buf) 505 | 506 | rbuf = self.mcp2221a.read(PACKET_SIZE) 507 | return rbuf[8] 508 | 509 | ####################################################################### 510 | # I2C Cancel 511 | ####################################################################### 512 | 513 | def I2C_Cancel(self): 514 | buf = self.compile_packet([0x00, 0x10]) 515 | buf[2 + 1] = 0x10 # Cancel current I2C/SMBus transfer (sub-command) 516 | self.mcp2221a.write(buf) 517 | 518 | self.mcp2221a.read(PACKET_SIZE) 519 | # time.sleep(0.1) 520 | 521 | ####################################################################### 522 | # I2C Write 523 | ####################################################################### 524 | def I2C_Write(self, addrs, data): 525 | """ Writes a block of data with Start and Stop c condition on bus 526 | :param int addrs: 7-bit I2C slave address 527 | :param list data: list of int 528 | 529 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.5 530 | """ 531 | buf = self.compile_packet([0x00, 0x90]) 532 | self._i2c_write(addrs, data, buf) 533 | 534 | def I2C_Write_Repeated(self, addrs, data): 535 | """ Writes a block of data with Repeated Start and Stop conditions on bus 536 | :param int addrs: 7-bit I2C slave address 537 | :param list data: list of int 538 | 539 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.6 540 | """ 541 | buf = self.compile_packet([0x00, 0x92]) 542 | self._i2c_write(addrs, data, buf) 543 | 544 | def I2C_Write_No_Stop(self, addrs, data): 545 | """ Writes a block of data with Start condition on bus 546 | :param int addrs: 7-bit I2C slave address 547 | :param list data: list of int 548 | 549 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.7 550 | """ 551 | buf = self.compile_packet([0x00, 0x94]) 552 | self._i2c_write(addrs, data, buf) 553 | 554 | def _i2c_write(self, addrs, data, buf): 555 | 556 | buf[1 + 1] = (len(data) & 0x00FF) # Cancel current I2C/SMBus transfer (sub-command) 557 | buf[2 + 1] = (len(data) & 0xFF00) >> 8 # Set I2C/SMBus communication speed (sub-command) 558 | # The I2C/SMBus system clock divider that will be used to establish the communication speed 559 | buf[3 + 1] = 0xFF & (addrs << 1) 560 | for i in range(len(data)): 561 | # print ("{:d}: 0x{:02x}".format(i,data[i])) 562 | buf[4 + 1 + i] = data[ 563 | i] # The I2C/SMBus system clock divider that will be used to establish the communication speed 564 | self.mcp2221a.write(buf) 565 | rbuf = self.mcp2221a.read(PACKET_SIZE) 566 | time.sleep(0.008) 567 | 568 | ####################################################################### 569 | # I2C Read 570 | ####################################################################### 571 | def I2C_Read(self, addrs, size): 572 | """ Reads a block of data with Start and Stop conditions on bus 573 | :param int addrs: 7-bit I2C slave address 574 | :param int size: size of read out in bytes 575 | 576 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.8 577 | """ 578 | buf = self.compile_packet([0x00, 0x91]) 579 | return self._i2c_read(addrs, size, buf) 580 | 581 | def I2C_Read_Repeated(self, addrs, size): 582 | """ Reads a block of data with Repeated Start and Stop conditions on bus 583 | :param int addrs: 7-bit I2C slave address 584 | :param int size: size of read out in bytes 585 | 586 | Referring to MCP2221A Datasheet(Rev.B 2017), section 3.1.9 587 | """ 588 | buf = self.compile_packet([0x00, 0x93]) 589 | return self._i2c_read(addrs, size, buf) 590 | 591 | def _i2c_read(self, addrs, size, buf): 592 | 593 | buf[1 + 1] = (size & 0x00FF) # Read LEN 594 | buf[2 + 1] = (size & 0xFF00) >> 8 # Read LEN 595 | buf[3 + 1] = 0xFF & (addrs << 1) # addrs 596 | self.mcp2221a.write(buf) 597 | rbuf = self.mcp2221a.read(PACKET_SIZE) 598 | if (rbuf[1] != 0x00): 599 | # print("[0x91:0x{:02x},0x{:02x},0x{:02x}]".format(rbuf[1],rbuf[2],rbuf[3])) 600 | self.I2C_Cancel() 601 | self.I2C_Init() 602 | raise RuntimeError("I2C Read Data Failed: Code " + rbuf[1]) 603 | time.sleep(self.MCP2221_I2C_SLEEP) 604 | 605 | buf = self.compile_packet([0x00, 0x40]) 606 | buf[1 + 1] = 0x00 607 | buf[2 + 1] = 0x00 608 | buf[3 + 1] = 0x00 609 | self.mcp2221a.write(buf) 610 | rbuf = self.mcp2221a.read(PACKET_SIZE) 611 | if (rbuf[1] != 0x00): 612 | # print("[0x40:0x{:02x},0x{:02x},0x{:02x}]".format(rbuf[1],rbuf[2],rbuf[3])) 613 | self.I2C_Cancel() 614 | self.I2C_Init() 615 | print("You can try increasing environment variable MCP2221_I2C_SLEEP") 616 | raise RuntimeError("I2C Read Data - Get I2C Data Failed: Code " + rbuf[1]) 617 | if (rbuf[2] == 0x00 and rbuf[3] == 0x00): 618 | self.I2C_Cancel() 619 | self.I2C_Init() 620 | return rbuf[4] 621 | if (rbuf[2] == 0x55 and rbuf[3] == size): 622 | rdata = [0] * size 623 | for i in range(size): 624 | rdata[i] = rbuf[4 + i] 625 | return rdata 626 | 627 | ####################################################################### 628 | # reset 629 | ####################################################################### 630 | def Reset(self): 631 | print("Reset") 632 | buf = self.compile_packet([0x00, 0x70, 0xAB, 0xCD, 0xEF]) 633 | 634 | self.mcp2221a.write(buf) 635 | time.sleep(1) 636 | --------------------------------------------------------------------------------