MindMotion MM32F3277 SoftI2C function test

Posted by juancarlosc on Fri, 26 Nov 2021 02:06:32 +0100

Introduction: Test the migrated version with SoftI2C sent from MindMotion SuYong. The porting function of the SoftI2C is preliminarily proved. Using OLED display test, you can see that the command of the external bus of this version of SoftI2C is very slow. After testing, it can be seen that this version of SoftI2C is not ready for the control of the output clock.

Keywords: I2C, MM32, micropathon

 

§01 MM32F3277 MicroPython

  today (November 25, 2021), I received a porting version from MindMotion SuYong to add I2C bus function to the microphoton of MM32F3277.

Bluish[SY]:
Mr. Zhuo, only such a ghost came out these two days

Bluish[SY]:
Hardware i2c Driver, I think I need to operate the knife myself

Bluish[SY]:
If soft i2c If it works, I'll start with the hardware first spi Optimization and pwm Channel expansion

Bluish[SY]:
This can also be done for us i2c Hardware driven colleagues take a moment to let her adjust the code, or ask for help from zhufei

  test this version below.

1, Test micro Python

1. Download micro Python to MCU

▲ figure 1.1.1 download microphoton to MM32F3277

2. Preliminary test

(1) REPL test machine module

>>> import machine
>>> dir(machine)
['__name__', 'ADC', 'DAC', 'PWM', 'Pin', 'SDCard', 'SPI', 'SoftI2C', 'SoftSPI', 'UART', 'freq', 'mem16', 'mem32', 'mem8']
>>> 

3. Programming test

  for the documents on I2C programming of micropathon, see: MicroPython class I2C

▲ figure 1.1.2 I2C use case

(1) Preliminary test

  I. test procedure
from machine                import I2C
import utime

i2c = I2C(freq400000)
i2c.scan()
i2c.writeto(42, b'123')
  Ⅱ. Output results
>> Download MicroPython : 22 lines/515 characters.
>> -------------------------------------------------------------------------

Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
ImportError: can't import name I2C
>>> 

(2)import SoftI2C

  I. test code
from machine                import Pin,SoftI2C
i2c = SoftI2C(freq400000)
i2c.scan()
i2c.writeto(42, b'123')
  Ⅱ. Output results
>> Download MicroPython : 22 lines/524 characters.
>> -------------------------------------------------------------------------

Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
ImportError: module not found
>>> 

4. Test port

2, Test I2C OLED

  in Lexin esp8266 module micro Python development board MQTT IOT artificial intelligence minimum system The I2C OLED module has been tested. Next, connect it to MM32F3277.

1. Connecting OLED s

▲ figure 1.2.1 connect the OLED to the test board on the bread board

2. Preliminary test

(1) Scan bus

  I. test code
from machine                import Pin,SoftI2C
import utime

print("Test I2C")

scl = Pin('PA0')
sda = Pin('PA1')

i2c = SoftI2C(scl, sda, freq=100000)

ret = i2c.scan()
print(ret)
  Ⅱ. Output results
>> Download MicroPython : 26 lines/584 characters.
>> -------------------------------------------------------------------------

Test I2C
[60]
>>> 

The Slave address of I2C obtained from the scan above is 60 (0x3C), which is different from that in Lexin esp8266 module micro Python development board MQTT IOT artificial intelligence minimum system The given address is consistent.

(2) Test write

  I. test code
from machine                import Pin,SoftI2C
import utime
from micropython import const

scl = Pin('PA0')
sda = Pin('PA1')

i2c = SoftI2C(scl, sda, freq=100000)

ret = i2c.scan()
print(ret)

temp = bytearray(2)
i2c.start()
temp[0] = 120
temp[1] = 1
i2c.write(temp)
i2c.stop()

print('Test end.')
  Ⅱ. Output results
>> Download MicroPython : 34 lines/760 characters.
>> -------------------------------------------------------------------------

[60]
2
Test end.
>>> 

  you can see that two bytes are written.

3. Initialize OLED

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTI2C.PY                   -- by Dr. ZhuoQing 2021-11-25
#
# Note:
#============================================================
from machine                import Pin,SoftI2C
import utime
from micropython import const
#------------------------------------------------------------
scl = Pin('PA0')
sda = Pin('PA1')
i2c = SoftI2C(scl, sda, freq=100000)
#------------------------------------------------------------
SET_CONTRAST        = const(0x81)
SET_ENTIRE_ON       = const(0xa4)
SET_NORM_INV        = const(0xa6)
SET_DISP            = const(0xae)
SET_MEM_ADDR        = const(0x20)
SET_COL_ADDR        = const(0x21)
SET_PAGE_ADDR       = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP       = const(0xa0)
SET_MUX_RATIO       = const(0xa8)
SET_COM_OUT_DIR     = const(0xc0)
SET_DISP_OFFSET     = const(0xd3)
SET_COM_PIN_CFG     = const(0xda)
SET_DISP_CLK_DIV    = const(0xd5)
SET_PRECHARGE       = const(0xd9)
SET_VCOM_DESEL      = const(0xdb)
SET_CHARGE_PUMP     = const(0x8d)
#------------------------------------------------------------
class SSD1306():
    def __init__(self, width, height, external_vcc):
        self.width = width
        self.height = height
        self.external_vcc = external_vcc
        self.pages = self.height // 8
        self.buffer = bytearray(self.pages * self.width)
        self.init_display()
    def init_display(self):
        for cmd in (
            SET_DISP | 0x00,            # off
            SET_MEM_ADDR, 0x00,         # horizontal
            SET_DISP_START_LINE | 0x00,
            SET_SEG_REMAP | 0x01,       # column addr 127 mapped to SEG0
            SET_MUX_RATIO, self.height - 1,
            SET_COM_OUT_DIR | 0x08,     # scan from COM[N] to COM0
            SET_DISP_OFFSET, 0x00,
            SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
            SET_DISP_CLK_DIV, 0x80,
            SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
            SET_VCOM_DESEL, 0x30,       # 0.83*Vcc
            SET_CONTRAST, 0xff,         # maximum
            SET_ENTIRE_ON,              # output follows RAM contents
            SET_NORM_INV,               # not inverted
            SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
            SET_DISP | 0x01):           # on
            self.write_cmd(cmd)
        self.fill(0xff)
        self.show()
    def fill(self, c):
        for i in range(len(self.buffer)):
            self.buffer[i] = c
    def poweroff(self):
        self.write_cmd(SET_DISP | 0x00)
    def poweron(self):
        self.write_cmd(SET_DISP | 0x01)
    def contrast(self, contrast):
        self.write_cmd(SET_CONTRAST)
        self.write_cmd(contrast)
    def invert(self, invert):
        self.write_cmd(SET_NORM_INV | (invert & 1))
    def show(self):
        x0 = 0
        x1 = self.width - 1
        if self.width == 64:
            x0 += 32
            x1 += 32
        self.write_cmd(SET_COL_ADDR)
        self.write_cmd(x0)
        self.write_cmd(x1)
        self.write_cmd(SET_PAGE_ADDR)
        self.write_cmd(0)
        self.write_cmd(self.pages - 1)
        self.write_data(self.buffer)
class SSD1306_I2C(SSD1306):
    def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
        self.i2c = i2c
        self.addr = addr
        self.temp = bytearray(2)
        super().__init__(width, height, external_vcc)
    def write_cmd(self, cmd):
        self.temp[0] = 0x80 # Co=1, D/C#=0
        self.temp[1] = cmd
        self.i2c.writeto(self.addr, self.temp)
    def write_data(self, buf):
        self.temp[0] = self.addr << 1
        self.temp[1] = 0x40         # Co=0, D/C#=1
        self.i2c.start()
        self.i2c.write(self.temp)
        self.i2c.write(buf)
        self.i2c.stop()
#------------------------------------------------------------
oled = SSD1306_I2C(128, 64, i2c, addr=0x3c)
#oled.text('Hello world!', 0, 0)
#oled.text('OLED test', 0, 50)
#oled. show()
#------------------------------------------------------------
#        END OF FILE : TESTI2C.PY
#============================================================

   the following is the process of writing 1024 bytes during OLED initialization. The process is abnormally slow.

▲ figure 1.2.2 refresh OLED process

   the reason why it is so slow is that the baud rate at this time is only 400Hz, which is much different from the initialized baud rate by testing the waveforms of SCL and SDA through the oscilloscope.

▲ figure 1.2.3 writing process of I2C bus

 

※ test summary ※

  test the transplanted version with SoftI2C sent from MindMotion SuYong. The porting function of the SoftI2C is preliminarily proved. Using OLED display test, you can see that the command of the external bus of this version of SoftI2C is very slow.

  after testing, it can be seen that this version of SoftI2C is not ready for the control of the output clock.

■ links to relevant literature:

● relevant chart links:

Topics: micropython I2C